PPSSPP UI: Implement password masking in popup text inputs

This commit is contained in:
Henrik Rydgård 2024-09-26 10:58:58 +02:00
parent f020d1d815
commit 1b158940ac
8 changed files with 27 additions and 10 deletions

View file

@ -528,7 +528,7 @@ EventReturn PopupTextInputChoice::HandleClick(EventParams &e) {
// Choose method depending on platform capabilities.
if (System_GetPropertyBool(SYSPROP_HAS_TEXT_INPUT_DIALOG)) {
System_InputBoxGetString(token_, text_, *value_, passwordDisplay_, [=](const std::string &enteredValue, int) {
System_InputBoxGetString(token_, text_, *value_, passwordMasking_, [=](const std::string &enteredValue, int) {
*value_ = StripSpaces(enteredValue);
EventParams params{};
OnChange.Trigger(params);
@ -537,6 +537,7 @@ EventReturn PopupTextInputChoice::HandleClick(EventParams &e) {
}
TextEditPopupScreen *popupScreen = new TextEditPopupScreen(value_, placeHolder_, ChopTitle(text_), maxLen_);
popupScreen->SetPasswordMasking(passwordMasking_);
if (System_GetPropertyBool(SYSPROP_KEYBOARD_IS_SOFT)) {
popupScreen->SetAlignTop(true);
}
@ -570,6 +571,7 @@ void TextEditPopupScreen::CreatePopupContents(UI::ViewGroup *parent) {
edit_ = new TextEdit(textEditValue_, Title(), placeholder_, new LinearLayoutParams(1.0f));
edit_->SetMaxLen(maxLen_);
edit_->SetTextColor(dc.theme->popupStyle.fgColor);
edit_->SetPasswordMasking(passwordMasking_);
lin->Add(edit_);
UI::SetFocusedView(edit_);
@ -628,7 +630,7 @@ void AbstractChoiceWithValueDisplay::Draw(UIContext &dc) {
std::string valueText = ValueText();
if (passwordDisplay_) {
if (passwordMasking_) {
// Replace all characters with stars.
memset(&valueText[0], '*', valueText.size());
}

View file

@ -150,6 +150,10 @@ public:
const char *tag() const override { return "TextEditPopup"; }
void SetPasswordMasking(bool masking) {
passwordMasking_ = masking;
}
Event OnChange;
private:
@ -159,6 +163,7 @@ private:
std::string textEditValue_;
std::string placeholder_;
int maxLen_;
bool passwordMasking_ = false;
};
struct ContextMenuItem {

View file

@ -1142,18 +1142,25 @@ void TextEdit::Draw(UIContext &dc) {
Bounds textBounds = bounds_;
textBounds.x = textX - scrollPos_;
std::string textToDisplay = text_;
if (passwordMasking_) {
for (int i = 0; i < textToDisplay.size(); i++) {
textToDisplay[i] = '*';
}
}
if (text_.empty()) {
if (placeholderText_.size()) {
uint32_t c = textColor & 0x50FFFFFF;
dc.DrawTextRect(placeholderText_, bounds_, c, ALIGN_CENTER);
}
} else {
dc.DrawTextRect(text_, textBounds, textColor, ALIGN_VCENTER | ALIGN_LEFT | align_);
dc.DrawTextRect(textToDisplay, textBounds, textColor, ALIGN_VCENTER | ALIGN_LEFT | align_);
}
if (HasFocus()) {
// Hack to find the caret position. Might want to find a better way...
dc.MeasureText(dc.theme->uiFont, 1.0f, 1.0f, text_.substr(0, caret_), &w, &h, ALIGN_VCENTER | ALIGN_LEFT | align_);
dc.MeasureText(dc.theme->uiFont, 1.0f, 1.0f, textToDisplay.substr(0, caret_), &w, &h, ALIGN_VCENTER | ALIGN_LEFT | align_);
float caretX = w - scrollPos_;
if (caretX > bounds_.w) {
scrollPos_ += caretX - bounds_.w;

View file

@ -825,14 +825,14 @@ public:
void GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const override;
void SetPasswordDisplay() {
passwordDisplay_ = true;
passwordMasking_ = true;
}
protected:
virtual std::string ValueText() const = 0;
float CalculateValueScale(const UIContext &dc, std::string_view valueText, float availWidth) const;
bool passwordDisplay_ = false;
bool passwordMasking_ = false;
};
class ChoiceWithCallbackValueDisplay : public AbstractChoiceWithValueDisplay {
@ -1026,6 +1026,9 @@ public:
const std::string &GetText() const { return text_; }
void SetMaxLen(size_t maxLen) { maxLen_ = maxLen; }
void SetTextAlign(int align) { align_ = align; } // Only really useful for setting FLAG_DYNAMIC_ASCII
void SetPasswordMasking(bool masking) {
passwordMasking_ = masking;
}
void FocusChanged(int focusFlags) override;
void GetContentDimensions(const UIContext &dc, float &w, float &h) const override;
@ -1050,6 +1053,7 @@ private:
int scrollPos_ = 0;
size_t maxLen_;
bool ctrlDown_ = false; // TODO: Make some global mechanism for this.
bool passwordMasking_ = false;
int align_ = 0;
// TODO: Selections
};

View file

@ -97,7 +97,7 @@ UI::EventReturn ChatMenu::OnSubmit(UI::EventParams &e) {
sendChat(chat);
#elif PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(SWITCH) || PPSSPP_PLATFORM(IOS)
auto n = GetI18NCategory(I18NCat::NETWORKING);
System_InputBoxGetString(token_, n->T("Chat"), "", [](const std::string &value, int) {
System_InputBoxGetString(token_, n->T("Chat"), "", false, [](const std::string &value, int) {
sendChat(value);
});
#endif

View file

@ -1546,7 +1546,7 @@ bool NativeSaveSecret(std::string_view nameOfSecret, std::string_view data) {
if (data.empty() && File::Exists(path)) {
return File::Delete(path);
} else if (!File::WriteDataToFile(false, data.data(), data.size(), path)) {
WARN_LOG(Log::System, "Failed to write secret '%s' to path '%s'", nameOfSecret, path.c_str());
WARN_LOG(Log::System, "Failed to write secret '%.*s' to path '%s'", (int)nameOfSecret.size(), nameOfSecret.data(), path.c_str());
return false;
}
return true;

View file

@ -296,7 +296,7 @@ void RetroAchievementsSettingsScreen::CreateAccountTab(UI::ViewGroup *viewGroup)
Achievements::Logout();
return UI::EVENT_DONE;
});
} else if (false && System_GetPropertyBool(SYSPROP_HAS_LOGIN_DIALOG)) {
} else if (System_GetPropertyBool(SYSPROP_HAS_LOGIN_DIALOG)) {
viewGroup->Add(new Choice(di->T("Log in")))->OnClick.Add([=](UI::EventParams &) -> UI::EventReturn {
std::string title = StringFromFormat("RetroAchievements: %s", di->T_cstr("Log in"));
System_AskUsernamePassword(GetRequesterToken(), title, [](const std::string &value, int) {

View file

@ -1120,7 +1120,6 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string
PushCommand("copy_to_clipboard", param1);
return true;
case SystemRequestType::INPUT_TEXT_MODAL:
case SystemRequestType::INPUT_PASSWORD_MODAL:
{
std::string serialized = StringFromFormat("%d:@:%s:@:%s", requestId, param1.c_str(), param2.c_str());
PushCommand("inputbox", serialized.c_str());