Rework some IAP/Gold UI. Minor title screen tweak

This commit is contained in:
Henrik Rydgård
2025-11-23 21:47:43 +01:00
parent 0cab218877
commit bf9493910a
8 changed files with 81 additions and 41 deletions
+1
View File
@@ -234,6 +234,7 @@ enum SystemProperty {
SYSPROP_HAS_TRASH_BIN,
SYSPROP_USE_IAP,
SYSPROP_USE_APP_STORE,
SYSPROP_SUPPORTS_SHARE_TEXT,
};
+4
View File
@@ -518,6 +518,10 @@ void Choice::Draw(UIContext &dc) {
if (image_.isValid() && text_.empty()) {
dc.Draw()->DrawImageRotated(image_, bounds_.centerX(), bounds_.centerY(), imgScale_, imgRot_, style.fgColor, imgFlipH_);
if (shine_) {
Bounds b = Bounds::FromCenter(bounds_.centerX(), bounds_.centerY(), bounds_.h * 0.4f);
DrawIconShine(dc, b.Inset(5.0f, 5.0f), 0.65f, false);
}
} else if (!text_.empty() && !hideTitle_) {
dc.SetFontStyle(dc.GetTheme().uiFont);
+49 -27
View File
@@ -27,11 +27,11 @@ void IAPScreen::CreateViews() {
LinearLayout *leftColumnItems;
if (portrait) {
leftColumnItems = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, 1.0f, UI::Margins(15,15)));
leftColumnItems = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, UI::Margins(12, 12)));
root_->Add(leftColumnItems);
} else {
ViewGroup *leftColumnContainer = new AnchorLayout(new LinearLayoutParams(1.0f, UI::Gravity::G_HCENTER));
leftColumnItems = new LinearLayout(ORIENT_VERTICAL, new AnchorLayoutParams(600, WRAP_CONTENT, NONE, 105, NONE, 15));
leftColumnItems = new LinearLayout(ORIENT_VERTICAL, new AnchorLayoutParams(600, WRAP_CONTENT, NONE, 105, NONE, 12));
leftColumnContainer->Add(leftColumnItems);
root_->Add(leftColumnContainer);
}
@@ -55,25 +55,43 @@ void IAPScreen::CreateViews() {
leftColumnItems->Add(new TextView("Henrik Rydgård"));
leftColumnItems->Add(new TextView("(hrydgard)"));
ViewGroup *rightColumnItems = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(300, WRAP_CONTENT, UI::Margins(15,15)));
float weight = 0.0f;
if (portrait)
weight = 1.0f; // hack to lift the buttons up.
ViewGroup *rightColumnItems = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(350, WRAP_CONTENT, weight, UI::Margins(12, 12)));
root_->Add(rightColumnItems);
if (!bought) {
Choice *buyButton = rightColumnItems->Add(new Choice(mm->T("Buy PPSSPP Gold")));
ImageID image;
#if 1 || PPSSPP_PLATFORM(ANDROID)
image = ImageID("I_LOGO_PLAY_STORE");
#elif PPSSPP_PLATFORM(IOS)
image = ImageID("I_LOGO_APP_STORE");
#endif
Choice *buyButton = rightColumnItems->Add(new Choice(mm->T("Buy PPSSPP Gold"), image));
buyButton->SetIcon(ImageID("I_ICON_GOLD"), 0.5f);
buyButton->SetShine(true);
const int requesterToken = GetRequesterToken();
buyButton->OnClick.Add([this, requesterToken](UI::EventParams &) {
INFO_LOG(Log::System, "Showing purchase UI...");
System_IAPMakePurchase(requesterToken, "org.ppsspp.gold", [this](const char *responseString, int intValue) {
INFO_LOG(Log::System, "PPSSPP Gold purchase successful!");
auto di = GetI18NCategory(I18NCat::DIALOG);
g_OSD.Show(OSDType::MESSAGE_SUCCESS, di->T("GoldThankYou", "Thank you for supporting the PPSSPP project!"), 3.0f);
RecreateViews();
}, []() {
WARN_LOG(Log::System, "Purchase failed or cancelled!");
});
// TODO: What do we do here?
if (useIAP_) {
System_IAPMakePurchase(requesterToken, "org.ppsspp.gold", [this](const char *responseString, int intValue) {
INFO_LOG(Log::System, "PPSSPP Gold purchase successful!");
auto di = GetI18NCategory(I18NCat::DIALOG);
g_OSD.Show(OSDType::MESSAGE_SUCCESS, di->T("GoldThankYou", "Thank you for supporting the PPSSPP project!"), 3.0f);
RecreateViews();
}, []() {
WARN_LOG(Log::System, "Purchase failed or cancelled!");
});
} else {
#if PPSSPP_PLATFORM(ANDROID)
System_LaunchUrl(LaunchUrlType::BROWSER_URL, "market://details?id=org.ppsspp.ppssppgold");
#else
System_LaunchUrl(LaunchUrlType::BROWSER_URL, "https://www.ppsspp.org/buygold");
#endif
}
});
}
@@ -87,19 +105,23 @@ void IAPScreen::CreateViews() {
backButton->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
}
// Put the restore purchases button in the bottom right corner. It's rarely useful, but needed.
rightColumnItems->Add(new Spacer(new LinearLayoutParams(1.0f)));
Choice *restorePurchases = new Choice(di->T("Restore purchase"));
const int requesterToken = GetRequesterToken();
restorePurchases->OnClick.Add([this, requesterToken, restorePurchases](UI::EventParams &) {
restorePurchases->SetEnabled(false);
INFO_LOG(Log::System, "Requesting purchase restore");
System_IAPRestorePurchases(requesterToken, [this](const char *responseString, int) {
INFO_LOG(Log::System, "Successfully restored purchases!");
RecreateViews();
}, []() {
WARN_LOG(Log::System, "Failed restoring purchases");
if (useIAP_) {
// Put the restore purchases button in the bottom right corner in landscape. It's rarely useful, but needed.
if (!portrait) {
rightColumnItems->Add(new Spacer(new LinearLayoutParams(1.0f)));
}
Choice *restorePurchases = new Choice(di->T("Restore purchase"));
const int requesterToken = GetRequesterToken();
restorePurchases->OnClick.Add([this, requesterToken, restorePurchases](UI::EventParams &) {
restorePurchases->SetEnabled(false);
INFO_LOG(Log::System, "Requesting purchase restore");
System_IAPRestorePurchases(requesterToken, [this](const char *responseString, int) {
INFO_LOG(Log::System, "Successfully restored purchases!");
RecreateViews();
}, []() {
WARN_LOG(Log::System, "Failed restoring purchases");
});
});
});
rightColumnItems->Add(restorePurchases);
rightColumnItems->Add(restorePurchases);
}
}
+4
View File
@@ -9,6 +9,10 @@
class IAPScreen : public UIBaseDialogScreen {
public:
IAPScreen(bool useIAP) : UIBaseDialogScreen(), useIAP_(useIAP) {}
void CreateViews() override;
const char *tag() const override { return "IAP"; }
private:
// This screen can also be used to direct to Play Store purchases, for example.
bool useIAP_ = false;
};
+3 -3
View File
@@ -1541,12 +1541,12 @@ void MainScreen::OnCredits(UI::EventParams &e) {
void LaunchBuyGold(ScreenManager *screenManager) {
if (System_GetPropertyBool(SYSPROP_USE_IAP)) {
screenManager->push(new IAPScreen());
screenManager->push(new IAPScreen(true));
} else if (System_GetPropertyBool(SYSPROP_USE_APP_STORE)) {
screenManager->push(new IAPScreen(false));
} else {
#if PPSSPP_PLATFORM(IOS_APP_STORE)
System_LaunchUrl(LaunchUrlType::BROWSER_URL, "https://www.ppsspp.org/buygold_ios");
#elif PPSSPP_PLATFORM(ANDROID)
System_LaunchUrl(LaunchUrlType::BROWSER_URL, "market://details?id=org.ppsspp.ppssppgold");
#else
System_LaunchUrl(LaunchUrlType::BROWSER_URL, "https://www.ppsspp.org/buygold");
#endif
+12 -10
View File
@@ -425,7 +425,7 @@ void LogoScreen::touch(const TouchInput &touch) {
void LogoScreen::DrawForeground(UIContext &dc) {
using namespace Draw;
const Bounds &bounds = dc.GetBounds();
const Bounds &bounds = dc.GetLayoutBounds();
dc.Begin();
@@ -442,23 +442,25 @@ void LogoScreen::DrawForeground(UIContext &dc) {
auto cr = GetI18NCategory(I18NCat::PSPCREDITS);
auto gr = GetI18NCategory(I18NCat::GRAPHICS);
char temp[256];
const float startY = bounds.centerY() - 70;
// Manually formatting UTF-8 is fun. \xXX doesn't work everywhere.
snprintf(temp, sizeof(temp), "%s Henrik Rydg%c%crd", cr->T_cstr("created", "Created by"), 0xC3, 0xA5);
if (System_GetPropertyBool(SYSPROP_APP_GOLD)) {
UI::DrawIconShine(dc, Bounds::FromCenter(bounds.centerX() - 125, bounds.centerY() - 30, 60.0f), 0.7f, true);
dc.Draw()->DrawImage(ImageID("I_ICON_GOLD"), bounds.centerX() - 125, bounds.centerY() - 30, 1.2f, 0xFFFFFFFF, ALIGN_CENTER);
UI::DrawIconShine(dc, Bounds::FromCenter(bounds.centerX() - 125, startY, 60.0f), 0.7f, true);
dc.Draw()->DrawImage(ImageID("I_ICON_GOLD"), bounds.centerX() - 125, startY, 1.2f, 0xFFFFFFFF, ALIGN_CENTER);
} else {
dc.Draw()->DrawImage(ImageID("I_ICON"), bounds.centerX() - 125, bounds.centerY() - 30, 1.2f, 0xFFFFFFFF, ALIGN_CENTER);
dc.Draw()->DrawImage(ImageID("I_ICON"), bounds.centerX() - 125, startY, 1.2f, 0xFFFFFFFF, ALIGN_CENTER);
}
dc.Draw()->DrawImage(ImageID("I_LOGO"), bounds.centerX() + 45, bounds.centerY() - 30, 1.5f, 0xFFFFFFFF, ALIGN_CENTER);
dc.Draw()->DrawImage(ImageID("I_LOGO"), bounds.centerX() + 45, startY, 1.5f, 0xFFFFFFFF, ALIGN_CENTER);
//dc.Draw()->DrawTextShadow(UBUNTU48, "PPSSPP", bounds.w / 2, bounds.h / 2 - 30, textColor, ALIGN_CENTER);
dc.SetFontScale(1.0f, 1.0f);
dc.SetFontStyle(dc.GetTheme().uiFont);
dc.DrawText(temp, bounds.centerX(), bounds.centerY() + 40, textColor, ALIGN_CENTER);
dc.DrawText(cr->T_cstr("license", "Free Software under GPL 2.0+"), bounds.centerX(), bounds.centerY() + 70, textColor, ALIGN_CENTER);
dc.DrawText(temp, bounds.centerX(), startY + 70, textColor, ALIGN_CENTER);
dc.DrawText(cr->T_cstr("license", "Free Software under GPL 2.0+"), bounds.centerX(), startY + 110, textColor, ALIGN_CENTER);
int ppsspp_org_y = bounds.h / 2 + 130;
dc.DrawText("www.ppsspp.org", bounds.centerX(), ppsspp_org_y, textColor, ALIGN_CENTER);
dc.DrawText("www.ppsspp.org", bounds.centerX(), startY + 160, textColor, ALIGN_CENTER);
#if !PPSSPP_PLATFORM(UWP) || defined(_DEBUG)
// Draw the graphics API, except on UWP where it's always D3D11
@@ -468,7 +470,7 @@ void LogoScreen::DrawForeground(UIContext &dc) {
// Add some emoji for testing.
apiName += CodepointToUTF8(0x1F41B) + CodepointToUTF8(0x1F41C) + CodepointToUTF8(0x1F914);
#endif
dc.DrawText(apiName, bounds.centerX(), ppsspp_org_y + 50, textColor, ALIGN_CENTER);
dc.DrawText(apiName, bounds.centerX(), startY + 200, textColor, ALIGN_CENTER);
#endif
dc.Flush();
+3 -1
View File
@@ -448,7 +448,9 @@ bool System_GetPropertyBool(SystemProperty prop) {
case SYSPROP_HAS_ACCELEROMETER:
return g_InputManager.AnyAccelerometer();
case SYSPROP_USE_IAP:
return true;
return false;
case SYSPROP_USE_APP_STORE:
return false;
default:
return false;
}
+5
View File
@@ -482,6 +482,11 @@ bool System_GetPropertyBool(SystemProperty prop) {
#else
return false;
#endif
case SYSPROP_USE_IAP:
// Not yet implemented, we use a separate gold app on Android
return false;
case SYSPROP_USE_APP_STORE:
return true;
case SYSPROP_CAN_JIT:
return true;
case SYSPROP_ANDROID_SCOPED_STORAGE: