mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-16 16:00:30 +02:00
UI: Validate address entered in settings.
This commit is contained in:
1 parent
3bc2cad31b
commit
30dcc2a13a
4 files changed
+125
-4
No files matched your search
@@ -22,6 +22,7 @@
|
||||
#include "base/colorutil.h"
|
||||
#include "base/timeutil.h"
|
||||
#include "math/curves.h"
|
||||
#include "net/resolve.h"
|
||||
#include "gfx_es2/gpu_features.h"
|
||||
#include "gfx_es2/draw_buffer.h"
|
||||
#include "i18n/i18n.h"
|
||||
@@ -1468,6 +1469,7 @@ void HostnameSelectScreen::CreatePopupContents(UI::ViewGroup *parent) {
|
||||
using namespace UI;
|
||||
I18NCategory *sy = GetI18NCategory("System");
|
||||
I18NCategory *di = GetI18NCategory("Dialog");
|
||||
I18NCategory *n = GetI18NCategory("Networking");
|
||||
|
||||
LinearLayout *valueRow = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT, Margins(0, 0, 0, 10)));
|
||||
|
||||
@@ -1495,6 +1497,13 @@ void HostnameSelectScreen::CreatePopupContents(UI::ViewGroup *parent) {
|
||||
buttonsRow2->Add(new Button(di->T("Delete")))->OnClick.Handle(this, &HostnameSelectScreen::OnDeleteClick);
|
||||
buttonsRow2->Add(new Button(di->T("Delete all")))->OnClick.Handle(this, &HostnameSelectScreen::OnDeleteAllClick);
|
||||
buttonsRow2->Add(new Spacer(new LinearLayoutParams(1.0, G_RIGHT)));
|
||||
|
||||
errorView_ = parent->Add(new TextView(n->T("Invalid IP or hostname"), ALIGN_HCENTER, false, new LinearLayoutParams(Margins(0, 10, 0, 0))));
|
||||
errorView_->SetTextColor(0xFF3030FF);
|
||||
errorView_->SetVisibility(V_GONE);
|
||||
|
||||
progressView_ = parent->Add(new TextView(n->T("Validating address..."), ALIGN_HCENTER, false, new LinearLayoutParams(Margins(0, 10, 0, 0))));
|
||||
progressView_->SetVisibility(V_GONE);
|
||||
}
|
||||
|
||||
void HostnameSelectScreen::SendEditKey(int keyCode, int flags) {
|
||||
@@ -1528,6 +1537,81 @@ UI::EventReturn HostnameSelectScreen::OnDeleteAllClick(UI::EventParams &e) {
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
void HostnameSelectScreen::ResolverThread() {
|
||||
std::unique_lock<std::mutex> guard(resolverLock_);
|
||||
|
||||
while (resolverState_ != ResolverState::QUIT) {
|
||||
resolverCond_.wait(guard);
|
||||
|
||||
if (resolverState_ == ResolverState::QUEUED) {
|
||||
resolverState_ = ResolverState::PROGRESS;
|
||||
|
||||
addrinfo *resolved = nullptr;
|
||||
std::string err;
|
||||
toResolveResult_ = net::DNSResolve(toResolve_, "80", &resolved, err);
|
||||
if (resolved)
|
||||
net::DNSResolveFree(resolved);
|
||||
|
||||
resolverState_ = ResolverState::READY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool HostnameSelectScreen::CanComplete(DialogResult result) {
|
||||
if (result != DR_OK)
|
||||
return true;
|
||||
|
||||
std::string value = addrView_->GetText();
|
||||
if (lastResolved_ == value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Currently running.
|
||||
if (resolverState_ == ResolverState::PROGRESS)
|
||||
return false;
|
||||
|
||||
std::lock_guard<std::mutex> guard(resolverLock_);
|
||||
switch (resolverState_) {
|
||||
case ResolverState::PROGRESS:
|
||||
case ResolverState::QUIT:
|
||||
return false;
|
||||
|
||||
case ResolverState::QUEUED:
|
||||
case ResolverState::WAITING:
|
||||
break;
|
||||
|
||||
case ResolverState::READY:
|
||||
if (toResolve_ == value) {
|
||||
// Reset the state, nothing there now.
|
||||
resolverState_ = ResolverState::WAITING;
|
||||
toResolve_.clear();
|
||||
lastResolved_ = value;
|
||||
lastResolvedResult_ = toResolveResult_;
|
||||
|
||||
if (lastResolvedResult_) {
|
||||
errorView_->SetVisibility(UI::V_GONE);
|
||||
} else {
|
||||
errorView_->SetVisibility(UI::V_VISIBLE);
|
||||
}
|
||||
progressView_->SetVisibility(UI::V_GONE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Throw away that last result, it was for a different value.
|
||||
break;
|
||||
}
|
||||
|
||||
resolverState_ = ResolverState::QUEUED;
|
||||
toResolve_ = value;
|
||||
resolverCond_.notify_one();
|
||||
|
||||
progressView_->SetVisibility(UI::V_VISIBLE);
|
||||
errorView_->SetVisibility(UI::V_GONE);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void HostnameSelectScreen::OnCompleted(DialogResult result) {
|
||||
if (result == DR_OK)
|
||||
*value_ = addrView_->GetText();
|
||||
|
||||
+33
-1
@@ -18,6 +18,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "ppsspp_config.h"
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include "ui/ui_screen.h"
|
||||
#include "UI/MiscScreens.h"
|
||||
|
||||
@@ -179,20 +182,49 @@ class HostnameSelectScreen : public PopupScreen {
|
||||
public:
|
||||
HostnameSelectScreen(std::string *value, const std::string &title)
|
||||
: PopupScreen(title, "OK", "Cancel"), value_(value) {
|
||||
resolver_ = std::thread([](HostnameSelectScreen *thiz) {
|
||||
thiz->ResolverThread();
|
||||
}, this);
|
||||
}
|
||||
~HostnameSelectScreen() {
|
||||
resolverState_ = ResolverState::QUIT;
|
||||
resolverCond_.notify_one();
|
||||
resolver_.join();
|
||||
}
|
||||
|
||||
void CreatePopupContents(UI::ViewGroup *parent) override;
|
||||
|
||||
protected:
|
||||
void OnCompleted(DialogResult result) override;
|
||||
bool CanComplete(DialogResult result) override;
|
||||
|
||||
private:
|
||||
void ResolverThread();
|
||||
void SendEditKey(int keyCode, int flags = 0);
|
||||
UI::EventReturn OnNumberClick(UI::EventParams &e);
|
||||
UI::EventReturn OnPointClick(UI::EventParams &e);
|
||||
UI::EventReturn OnDeleteClick(UI::EventParams &e);
|
||||
UI::EventReturn OnDeleteAllClick(UI::EventParams &e);
|
||||
|
||||
enum class ResolverState {
|
||||
WAITING,
|
||||
QUEUED,
|
||||
PROGRESS,
|
||||
READY,
|
||||
QUIT,
|
||||
};
|
||||
|
||||
std::string *value_;
|
||||
UI::TextEdit *addrView_;
|
||||
UI::TextEdit *addrView_ = nullptr;
|
||||
UI::TextView *errorView_ = nullptr;
|
||||
UI::TextView *progressView_ = nullptr;
|
||||
|
||||
std::thread resolver_;
|
||||
ResolverState resolverState_ = ResolverState::WAITING;
|
||||
std::mutex resolverLock_;
|
||||
std::condition_variable resolverCond_;
|
||||
std::string toResolve_ = "";
|
||||
bool toResolveResult_ = false;
|
||||
std::string lastResolved_ = "";
|
||||
bool lastResolvedResult_ = false;
|
||||
};
|
||||
@@ -268,6 +268,8 @@ bool PopupScreen::key(const KeyInput &key) {
|
||||
void PopupScreen::update() {
|
||||
UIDialogScreen::update();
|
||||
|
||||
defaultButton_->SetEnabled(CanComplete(DR_OK));
|
||||
|
||||
float animatePos = 1.0f;
|
||||
|
||||
++frames_;
|
||||
@@ -314,10 +316,12 @@ void PopupScreen::SetPopupOrigin(const UI::View *view) {
|
||||
}
|
||||
|
||||
void PopupScreen::TriggerFinish(DialogResult result) {
|
||||
finishFrame_ = frames_;
|
||||
finishResult_ = result;
|
||||
if (CanComplete(result)) {
|
||||
finishFrame_ = frames_;
|
||||
finishResult_ = result;
|
||||
|
||||
OnCompleted(result);
|
||||
OnCompleted(result);
|
||||
}
|
||||
}
|
||||
|
||||
void PopupScreen::resized() {
|
||||
|
||||
@@ -84,6 +84,7 @@ protected:
|
||||
virtual bool FillVertical() const { return false; }
|
||||
virtual UI::Size PopupWidth() const { return 550; }
|
||||
virtual bool ShowButtons() const { return true; }
|
||||
virtual bool CanComplete(DialogResult result) { return true; }
|
||||
virtual void OnCompleted(DialogResult result) {}
|
||||
|
||||
virtual void update() override;
|
||||
|
||||
Reference in new issue
Block a user