Skip to content
Permalink
Browse files

Merge pull request #12394 from unknownbrackets/remote-iso

Allow pinning URLs to game browser
  • Loading branch information...
hrydgard committed Oct 7, 2019
2 parents cb8c57f + d00eff7 commit 8e44230d701ba37728809633dc149d42dff92994
Showing with 320 additions and 131 deletions.
  1. +3 −0 Common/FileUtil.cpp
  2. +3 −2 Core/Config.cpp
  3. +37 −30 UI/MainScreen.cpp
  4. +28 −5 UI/MainScreen.h
  5. +27 −88 UI/RemoteISOScreen.cpp
  6. +3 −1 UI/RemoteISOScreen.h
  7. +1 −1 UI/Store.cpp
  8. +201 −3 ext/native/file/path.cpp
  9. +17 −1 ext/native/file/path.h
@@ -136,6 +136,9 @@ static bool ResolvePathVista(const std::wstring &path, wchar_t *buf, DWORD bufSi
#endif

std::string ResolvePath(const std::string &path) {
if (startsWith(path, "http://") || startsWith(path, "https://")) {
return path;
}
#ifdef _WIN32
static const int BUF_SIZE = 32768;
wchar_t *buf = new wchar_t[BUF_SIZE] {};
@@ -1141,8 +1141,9 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) {
vPinnedPaths.clear();
for (auto it = pinnedPaths.begin(), end = pinnedPaths.end(); it != end; ++it) {
// Unpin paths that are deleted automatically.
if (File::Exists(it->second)) {
vPinnedPaths.push_back(File::ResolvePath(it->second));
const std::string &path = it->second;
if (startsWith(path, "http://") || startsWith(path, "https://") || File::Exists(path)) {
vPinnedPaths.push_back(File::ResolvePath(path));
}
}

@@ -365,11 +365,6 @@ void GameButton::Draw(UIContext &dc) {
dc.RebindTexture();
}

enum GameBrowserFlags {
FLAG_HOMEBREWSTOREBUTTON = 1
};


class DirButton : public UI::Button {
public:
DirButton(const std::string &path, UI::LayoutParams *layoutParams)
@@ -440,8 +435,8 @@ void DirButton::Draw(UIContext &dc) {
}
}

GameBrowser::GameBrowser(std::string path, bool allowBrowsing, bool *gridStyle, std::string lastText, std::string lastLink, int flags, UI::LayoutParams *layoutParams)
: LinearLayout(UI::ORIENT_VERTICAL, layoutParams), gameList_(0), path_(path), gridStyle_(gridStyle), allowBrowsing_(allowBrowsing), lastText_(lastText), lastLink_(lastLink), flags_(flags) {
GameBrowser::GameBrowser(std::string path, BrowseFlags browseFlags, bool *gridStyle, std::string lastText, std::string lastLink, UI::LayoutParams *layoutParams)
: LinearLayout(UI::ORIENT_VERTICAL, layoutParams), path_(path), gridStyle_(gridStyle), browseFlags_(browseFlags), lastText_(lastText), lastLink_(lastLink) {
using namespace UI;
Refresh();
}
@@ -510,10 +505,17 @@ bool GameBrowser::HasSpecialFiles(std::vector<std::string> &filenames) {
return false;
}

void GameBrowser::Update() {
LinearLayout::Update();
if (listingPending_ && path_.IsListingReady()) {
Refresh();
}
}

void GameBrowser::Refresh() {
using namespace UI;

homebrewStoreButton_ = 0;
homebrewStoreButton_ = nullptr;
// Kill all the contents
Clear();

@@ -523,14 +525,14 @@ void GameBrowser::Refresh() {
// No topbar on recent screen
if (DisplayTopBar()) {
LinearLayout *topBar = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT));
if (allowBrowsing_) {
if (browseFlags_ & BrowseFlags::NAVIGATE) {
topBar->Add(new Spacer(2.0f));
topBar->Add(new TextView(path_.GetFriendlyPath().c_str(), ALIGN_VCENTER | FLAG_WRAP_TEXT, true, new LinearLayoutParams(FILL_PARENT, 64.0f, 1.0f)));
#if defined(USING_WIN_UI) || defined(USING_QT_UI)
topBar->Add(new Choice(mm->T("Browse", "Browse..."), new LayoutParams(WRAP_CONTENT, 64.0f)))->OnClick.Handle(this, &GameBrowser::HomeClick);
#else
topBar->Add(new Choice(mm->T("Home"), new LayoutParams(WRAP_CONTENT, 64.0f)))->OnClick.Handle(this, &GameBrowser::HomeClick);
#endif
if (System_GetPropertyBool(SYSPROP_HAS_FILE_BROWSER)) {
topBar->Add(new Choice(mm->T("Browse", "Browse..."), new LayoutParams(WRAP_CONTENT, 64.0f)))->OnClick.Handle(this, &GameBrowser::HomeClick);
} else {
topBar->Add(new Choice(mm->T("Home"), new LayoutParams(WRAP_CONTENT, 64.0f)))->OnClick.Handle(this, &GameBrowser::HomeClick);
}
} else {
topBar->Add(new Spacer(new LinearLayoutParams(FILL_PARENT, 64.0f, 1.0f)));
}
@@ -556,12 +558,14 @@ void GameBrowser::Refresh() {
std::vector<DirButton *> dirButtons;
std::vector<GameButton *> gameButtons;

listingPending_ = !path_.IsListingReady();

std::vector<std::string> filenames;
if (HasSpecialFiles(filenames)) {
for (size_t i = 0; i < filenames.size(); i++) {
gameButtons.push_back(new GameButton(filenames[i], *gridStyle_, new UI::LinearLayoutParams(*gridStyle_ == true ? UI::WRAP_CONTENT : UI::FILL_PARENT, UI::WRAP_CONTENT)));
}
} else {
} else if (!listingPending_) {
std::vector<FileInfo> fileInfo;
path_.GetListing(fileInfo, "iso:cso:pbp:elf:prx:ppdmp:");
for (size_t i = 0; i < fileInfo.size(); i++) {
@@ -576,8 +580,8 @@ void GameBrowser::Refresh() {
isSaveData = true;

if (!isGame && !isSaveData) {
if (allowBrowsing_) {
dirButtons.push_back(new DirButton(fileInfo[i].name, new UI::LinearLayoutParams(UI::FILL_PARENT, UI::FILL_PARENT)));
if (browseFlags_ & BrowseFlags::NAVIGATE) {
dirButtons.push_back(new DirButton(fileInfo[i].fullName, fileInfo[i].name, new UI::LinearLayoutParams(UI::FILL_PARENT, UI::FILL_PARENT)));
}
} else {
gameButtons.push_back(new GameButton(fileInfo[i].fullName, *gridStyle_, new UI::LinearLayoutParams(*gridStyle_ == true ? UI::WRAP_CONTENT : UI::FILL_PARENT, UI::WRAP_CONTENT)));
@@ -586,7 +590,7 @@ void GameBrowser::Refresh() {
// Put RAR/ZIP files at the end to get them out of the way. They're only shown so that people
// can click them and get an explanation that they need to unpack them. This is necessary due
// to a flood of support email...
if (allowBrowsing_) {
if (browseFlags_ & BrowseFlags::ARCHIVES) {
fileInfo.clear();
path_.GetListing(fileInfo, "zip:rar:r01:7z:");
if (!fileInfo.empty()) {
@@ -604,7 +608,7 @@ void GameBrowser::Refresh() {
}
}

if (allowBrowsing_) {
if (browseFlags_ & BrowseFlags::NAVIGATE) {
gameList_->Add(new DirButton("..", new UI::LinearLayoutParams(UI::FILL_PARENT, UI::FILL_PARENT)))->
OnClick.Handle(this, &GameBrowser::NavigateClick);

@@ -616,6 +620,10 @@ void GameBrowser::Refresh() {
}
}

if (listingPending_) {
gameList_->Add(new UI::TextView(mm->T("Loading..."), ALIGN_CENTER, false, new UI::LinearLayoutParams(UI::FILL_PARENT, UI::FILL_PARENT)));
}

for (size_t i = 0; i < dirButtons.size(); i++) {
gameList_->Add(dirButtons[i])->OnClick.Handle(this, &GameBrowser::NavigateClick);
}
@@ -632,7 +640,7 @@ void GameBrowser::Refresh() {
}

// Show a button to toggle pinning at the very end.
if (allowBrowsing_) {
if (browseFlags_ & BrowseFlags::PIN) {
std::string caption = IsCurrentPathPinned() ? "-" : "+";
if (!*gridStyle_) {
caption = IsCurrentPathPinned() ? mm->T("UnpinPath", "Unpin") : mm->T("PinPath", "Pin");
@@ -641,11 +649,11 @@ void GameBrowser::Refresh() {
OnClick.Handle(this, &GameBrowser::PinToggleClick);
}

if (flags_ & FLAG_HOMEBREWSTOREBUTTON) {
if (browseFlags_ & BrowseFlags::HOMEBREW_STORE) {
Add(new Spacer());
homebrewStoreButton_ = Add(new Choice(mm->T("DownloadFromStore", "Download from the PPSSPP Homebrew Store"), new UI::LinearLayoutParams(UI::WRAP_CONTENT, UI::WRAP_CONTENT)));
} else {
homebrewStoreButton_ = 0;
homebrewStoreButton_ = nullptr;
}

if (!lastText_.empty() && gameButtons.empty()) {
@@ -788,7 +796,7 @@ void MainScreen::CreateViews() {
ScrollView *scrollRecentGames = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT));
scrollRecentGames->SetTag("MainScreenRecentGames");
GameBrowser *tabRecentGames = new GameBrowser(
"!RECENT", false, &g_Config.bGridView1, "", "", 0,
"!RECENT", BrowseFlags::NONE, &g_Config.bGridView1, "", "",
new LinearLayoutParams(FILL_PARENT, FILL_PARENT));
scrollRecentGames->Add(tabRecentGames);
gameBrowsers_.push_back(tabRecentGames);
@@ -806,12 +814,11 @@ void MainScreen::CreateViews() {
ScrollView *scrollHomebrew = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT));
scrollHomebrew->SetTag("MainScreenHomebrew");

GameBrowser *tabAllGames = new GameBrowser(g_Config.currentDirectory, true, &g_Config.bGridView2,
mm->T("How to get games"), "https://www.ppsspp.org/getgames.html", 0,
GameBrowser *tabAllGames = new GameBrowser(g_Config.currentDirectory, BrowseFlags::STANDARD, &g_Config.bGridView2,
mm->T("How to get games"), "https://www.ppsspp.org/getgames.html",
new LinearLayoutParams(FILL_PARENT, FILL_PARENT));
GameBrowser *tabHomebrew = new GameBrowser(GetSysDirectory(DIRECTORY_GAME), false, &g_Config.bGridView3,
GameBrowser *tabHomebrew = new GameBrowser(GetSysDirectory(DIRECTORY_GAME), BrowseFlags::HOMEBREW_STORE, &g_Config.bGridView3,
mm->T("How to get homebrew & demos", "How to get homebrew && demos"), "https://www.ppsspp.org/gethomebrew.html",
FLAG_HOMEBREWSTOREBUTTON,
new LinearLayoutParams(FILL_PARENT, FILL_PARENT));

Choice *hbStore = tabHomebrew->HomebrewStoreButton();
@@ -1261,7 +1268,7 @@ void UmdReplaceScreen::CreateViews() {
ScrollView *scrollRecentGames = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT));
scrollRecentGames->SetTag("UmdReplaceRecentGames");
GameBrowser *tabRecentGames = new GameBrowser(
"!RECENT", false, &g_Config.bGridView1, "", "", 0,
"!RECENT", BrowseFlags::NONE, &g_Config.bGridView1, "", "",
new LinearLayoutParams(FILL_PARENT, FILL_PARENT));
scrollRecentGames->Add(tabRecentGames);
leftColumn->AddTab(mm->T("Recent"), scrollRecentGames);
@@ -1271,8 +1278,8 @@ void UmdReplaceScreen::CreateViews() {
ScrollView *scrollAllGames = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT));
scrollAllGames->SetTag("UmdReplaceAllGames");

GameBrowser *tabAllGames = new GameBrowser(g_Config.currentDirectory, true, &g_Config.bGridView2,
mm->T("How to get games"), "https://www.ppsspp.org/getgames.html", 0,
GameBrowser *tabAllGames = new GameBrowser(g_Config.currentDirectory, BrowseFlags::STANDARD, &g_Config.bGridView2,
mm->T("How to get games"), "https://www.ppsspp.org/getgames.html",
new LinearLayoutParams(FILL_PARENT, FILL_PARENT));

scrollAllGames->Add(tabAllGames);
@@ -24,9 +24,30 @@
#include "ui/viewgroup.h"
#include "UI/MiscScreens.h"

enum GameBrowserFlags {
FLAG_HOMEBREWSTOREBUTTON = 1
};

enum class BrowseFlags {
NONE = 0,
NAVIGATE = 1,
ARCHIVES = 2,
PIN = 4,
HOMEBREW_STORE = 8,
STANDARD = 1 | 2 | 4,
};

static inline BrowseFlags operator |(const BrowseFlags &lhs, const BrowseFlags &rhs) {
return BrowseFlags((int)lhs | (int)rhs);
}

static inline bool operator &(const BrowseFlags &lhs, const BrowseFlags &rhs) {
return ((int)lhs & (int)rhs) != 0;
}

class GameBrowser : public UI::LinearLayout {
public:
GameBrowser(std::string path, bool allowBrowsing, bool *gridStyle_, std::string lastText, std::string lastLink, int flags = 0, UI::LayoutParams *layoutParams = 0);
GameBrowser(std::string path, BrowseFlags browseFlags, bool *gridStyle, std::string lastText, std::string lastLink, UI::LayoutParams *layoutParams = nullptr);

UI::Event OnChoice;
UI::Event OnHoldChoice;
@@ -37,6 +58,8 @@ class GameBrowser : public UI::LinearLayout {
void FocusGame(const std::string &gamePath);
void SetPath(const std::string &path);

void Update() override;

protected:
virtual bool DisplayTopBar();
virtual bool HasSpecialFiles(std::vector<std::string> &filenames);
@@ -57,15 +80,15 @@ class GameBrowser : public UI::LinearLayout {
UI::EventReturn HomeClick(UI::EventParams &e);
UI::EventReturn PinToggleClick(UI::EventParams &e);

UI::ViewGroup *gameList_;
UI::ViewGroup *gameList_ = nullptr;
PathBrowser path_;
bool *gridStyle_;
bool allowBrowsing_;
BrowseFlags browseFlags_;
std::string lastText_;
std::string lastLink_;
int flags_;
UI::Choice *homebrewStoreButton_;
UI::Choice *homebrewStoreButton_ = nullptr;
std::string focusGamePath_;
bool listingPending_ = false;
};

class RemoteISOBrowseScreen;

0 comments on commit 8e44230

Please sign in to comment.
You can’t perform that action at this time.