diff --git a/CMakeLists.txt b/CMakeLists.txt index 45b0837097..23fcbdf3fd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -767,6 +767,7 @@ set(NativeAppSource UI/GamepadEmu.cpp UI/OnScreenDisplay.cpp UI/ControlMappingScreen.cpp + UI/ReportScreen.cpp UI/Store.cpp UI/CwCheatScreen.cpp UI/InstallZipScreen.cpp diff --git a/Core/Reporting.cpp b/Core/Reporting.cpp index 762ae893e7..5de5c56560 100644 --- a/Core/Reporting.cpp +++ b/Core/Reporting.cpp @@ -140,7 +140,7 @@ namespace Reporting return ++spamProtectionCount >= SPAM_LIMIT; } - bool SendReportRequest(const char *uri, const std::string &data, Buffer *output = NULL) + bool SendReportRequest(const char *uri, const std::string &data, const std::string &mimeType, Buffer *output = NULL) { bool result = false; net::AutoInit netInit; @@ -153,7 +153,7 @@ namespace Reporting if (http.Resolve(ServerHostname(), ServerPort())) { http.Connect(); - http.POST("/report/message", data, "application/x-www-form-urlencoded", output); + http.POST("/report/message", data, mimeType, output); http.Disconnect(); result = true; } @@ -289,7 +289,7 @@ namespace Reporting { Payload &payload = payloadBuffer[pos]; - UrlEncoder postdata; + MultipartFormDataEncoder postdata; AddSystemInfo(postdata); AddGameInfo(postdata); AddConfigInfo(postdata); @@ -303,7 +303,8 @@ namespace Reporting payload.string1.clear(); payload.string2.clear(); - SendReportRequest("/report/message", postdata.ToString()); + postdata.Finish(); + SendReportRequest("/report/message", postdata.ToString(), postdata.GetMimeType()); break; } diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 45a93846be..81ba581525 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -44,6 +44,7 @@ #include "UI/CwCheatScreen.h" #include "UI/MiscScreens.h" #include "UI/ControlMappingScreen.h" +#include "UI/ReportScreen.h" #include "UI/Store.h" #include "UI/ui_atlas.h" #include "Core/Config.h" @@ -1176,6 +1177,13 @@ void GamePauseScreen::CreateViews() { if (g_Config.bEnableCheats) { rightColumnItems->Add(new Choice(i->T("Cheats")))->OnClick.Handle(this, &GamePauseScreen::OnCwCheat); } +#if 0 + // TODO, also might be nice to show overall compat rating here? + if (Reporting::IsEnabled()) { + I18NCategory *rp = GetI18NCategory("Reporting"); + rightColumnItems->Add(new Choice(rp->T("ReportButton", "Report Feedback")))->OnClick.Handle(this, &GamePauseScreen::OnReportFeedback); + } +#endif rightColumnItems->Add(new Spacer(25.0)); rightColumnItems->Add(new Choice(i->T("Exit to menu")))->OnClick.Handle(this, &GamePauseScreen::OnExitToMenu); @@ -1207,6 +1215,11 @@ UI::EventReturn GamePauseScreen::OnExitToMenu(UI::EventParams &e) { return UI::EVENT_DONE; } +UI::EventReturn GamePauseScreen::OnReportFeedback(UI::EventParams &e) { + screenManager()->push(new ReportScreen(gamePath_)); + return UI::EVENT_DONE; +} + UI::EventReturn GamePauseScreen::OnLoadState(UI::EventParams &e) { SaveState::LoadSlot(saveSlots_->GetSelection(), 0, 0); diff --git a/UI/MainScreen.h b/UI/MainScreen.h index d49bf6e519..cd586af0df 100644 --- a/UI/MainScreen.h +++ b/UI/MainScreen.h @@ -92,6 +92,7 @@ private: UI::EventReturn OnMainSettings(UI::EventParams &e); UI::EventReturn OnGameSettings(UI::EventParams &e); UI::EventReturn OnExitToMenu(UI::EventParams &e); + UI::EventReturn OnReportFeedback(UI::EventParams &e); UI::EventReturn OnSaveState(UI::EventParams &e); UI::EventReturn OnLoadState(UI::EventParams &e); diff --git a/UI/ReportScreen.cpp b/UI/ReportScreen.cpp new file mode 100644 index 0000000000..9c698a0c37 --- /dev/null +++ b/UI/ReportScreen.cpp @@ -0,0 +1,124 @@ +// Copyright (c) 2014- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#include +#include "i18n/i18n.h" +#include "gfx_es2/draw_buffer.h" +#include "ui/ui_context.h" +#include "UI/ReportScreen.h" + +#include "Core/Reporting.h" +#include "Common/Log.h" + +using namespace UI; + +class RatingChoice : public LinearLayout { +public: + RatingChoice(const char *captionKey, int *value, LayoutParams *layoutParams = 0); + + Event OnChoice; + +private: + void AddChoice(int i, const std::string &title); + EventReturn OnChoiceClick(EventParams &e); + + LinearLayout *group_; + int *value_; +}; + +RatingChoice::RatingChoice(const char *captionKey, int *value, LayoutParams *layoutParams) + : LinearLayout(ORIENT_VERTICAL, layoutParams), value_(value) { + SetSpacing(-8.0f); + + I18NCategory *rp = GetI18NCategory("Reporting"); + group_ = new LinearLayout(ORIENT_HORIZONTAL); + Add(new InfoItem(rp->T(captionKey), "")); + Add(group_); + + group_->SetSpacing(0.0f); + AddChoice(0, rp->T("Bad")); + AddChoice(1, rp->T("OK")); + AddChoice(2, rp->T("Great")); +} + +void RatingChoice::AddChoice(int i, const std::string &title) { + auto c = group_->Add(new StickyChoice(title, "")); + c->OnClick.Handle(this, &RatingChoice::OnChoiceClick); + if (*value_ == i) + c->Press(); +} + +EventReturn RatingChoice::OnChoiceClick(EventParams &e) { + // Unstick the other choices that weren't clicked. + for (int i = 0; i < 3; i++) { + auto v = group_->GetViewByIndex(i); + if (v != e.v) { + static_cast(v)->Release(); + } else { + *value_ = i; + } + } + + 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). + return OnChoice.Dispatch(e2); +} + +ReportScreen::ReportScreen(const std::string &gamePath) + : UIScreenWithGameBackground(gamePath), graphics_(-1), speed_(-1), gameplay_(-1) { +} + +EventReturn ReportScreen::HandleChoice(EventParams &e) { + submit_->SetEnabled(graphics_ >= 0 && speed_ >= 0 && gameplay_ >= 0); + return EVENT_DONE; +} + +void ReportScreen::CreateViews() { + I18NCategory *rp = GetI18NCategory("Reporting"); + I18NCategory *d = GetI18NCategory("Dialog"); + Margins actionMenuMargins(0, 100, 15, 0); + ViewGroup *leftColumn = new AnchorLayout(new LinearLayoutParams(1.0f)); + ViewGroup *leftColumnItems = new LinearLayout(ORIENT_VERTICAL); + ViewGroup *rightColumn = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(300, FILL_PARENT, actionMenuMargins)); + LinearLayout *rightColumnItems = new LinearLayout(ORIENT_VERTICAL); + + leftColumnItems->Add(new InfoItem(rp->T("FeedbackDesc", "How's the emulation? Let us and the community know!"), "")); + + // TODO: screenshot + leftColumnItems->Add(new RatingChoice("Graphics", &graphics_))->OnChoice.Handle(this, &ReportScreen::HandleChoice); + leftColumnItems->Add(new RatingChoice("Speed", &speed_))->OnChoice.Handle(this, &ReportScreen::HandleChoice); + leftColumnItems->Add(new RatingChoice("Gameplay", &gameplay_))->OnChoice.Handle(this, &ReportScreen::HandleChoice); + + rightColumnItems->SetSpacing(0.0f); + // TODO: Handle. + rightColumnItems->Add(new Choice(rp->T("Open Browser"))); + submit_ = new Choice(rp->T("Submit Feedback")); + // TODO: Handle. + rightColumnItems->Add(submit_); + submit_->SetEnabled(graphics_ >= 0 && speed_ >= 0 && gameplay_ >= 0); + + root_ = new LinearLayout(ORIENT_HORIZONTAL); + root_->Add(leftColumn); + root_->Add(rightColumn); + + leftColumn->Add(leftColumnItems); + leftColumn->Add(new Choice(d->T("Back"), "", false, new AnchorLayoutParams(150, WRAP_CONTENT, 10, NONE, NONE, 10)))->OnClick.Handle(this, &UIScreen::OnBack); + + rightColumn->Add(rightColumnItems); +} \ No newline at end of file diff --git a/UI/ReportScreen.h b/UI/ReportScreen.h new file mode 100644 index 0000000000..75d1cef1ae --- /dev/null +++ b/UI/ReportScreen.h @@ -0,0 +1,37 @@ +// Copyright (c) 2014- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#pragma once + +#include "base/functional.h" +#include "ui/ui_screen.h" +#include "ui/viewgroup.h" +#include "UI/MiscScreens.h" + +class ReportScreen : public UIScreenWithGameBackground { +public: + ReportScreen(const std::string &gamePath); + +protected: + UI::EventReturn HandleChoice(UI::EventParams &e); + virtual void CreateViews(); + + UI::Choice *submit_; + int graphics_; + int speed_; + int gameplay_; +}; diff --git a/UI/UI.vcxproj b/UI/UI.vcxproj index 9202890720..5589c1917e 100644 --- a/UI/UI.vcxproj +++ b/UI/UI.vcxproj @@ -32,6 +32,7 @@ + @@ -53,6 +54,7 @@ + diff --git a/UI/UI.vcxproj.filters b/UI/UI.vcxproj.filters index 8a3740e483..c118f00537 100644 --- a/UI/UI.vcxproj.filters +++ b/UI/UI.vcxproj.filters @@ -47,6 +47,9 @@ + + Screens + @@ -94,6 +97,10 @@ + + Screens + + diff --git a/android/jni/Android.mk b/android/jni/Android.mk index f1b1b6a762..9c7fdddc26 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -289,6 +289,7 @@ LOCAL_SRC_FILES := \ $(SRC)/UI/EmuScreen.cpp \ $(SRC)/UI/MainScreen.cpp \ $(SRC)/UI/MiscScreens.cpp \ + $(SRC)/UI/ReportScreen.cpp \ $(SRC)/UI/Store.cpp \ $(SRC)/UI/GamepadEmu.cpp \ $(SRC)/UI/GameInfoCache.cpp \