mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-02-16 12:05:38 +00:00
Refactored duplicate functionality in GridGameList and BasicGameList into
ISimpleGameList. BasicGameList and DetailedGameList now automatically switch as metadata changes.
This commit is contained in:
parent
9249d67048
commit
12ee215873
|
@ -193,10 +193,11 @@ set(ES_HEADERS
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/pugiXML/pugiconfig.hpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/pugiXML/pugiconfig.hpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/pugiXML/pugixml.hpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/pugiXML/pugixml.hpp
|
||||||
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/views/BasicGameListView.h
|
${CMAKE_CURRENT_SOURCE_DIR}/src/views/gamelist/BasicGameListView.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/views/DetailedGameListView.h
|
${CMAKE_CURRENT_SOURCE_DIR}/src/views/gamelist/DetailedGameListView.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/views/GameListView.h
|
${CMAKE_CURRENT_SOURCE_DIR}/src/views/gamelist/IGameListView.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/views/GridGameListView.h
|
${CMAKE_CURRENT_SOURCE_DIR}/src/views/gamelist/ISimpleGameListView.h
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src/views/gamelist/GridGameListView.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/views/SystemListView.h
|
${CMAKE_CURRENT_SOURCE_DIR}/src/views/SystemListView.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/views/SystemView.h
|
${CMAKE_CURRENT_SOURCE_DIR}/src/views/SystemView.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/views/ViewController.h
|
${CMAKE_CURRENT_SOURCE_DIR}/src/views/ViewController.h
|
||||||
|
@ -271,10 +272,11 @@ set(ES_SOURCES
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/resources/ResourceManager.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/resources/ResourceManager.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureResource.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/resources/TextureResource.cpp
|
||||||
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/views/BasicGameListView.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/views/gamelist/BasicGameListView.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/views/DetailedGameListView.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/views/gamelist/DetailedGameListView.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/views/GameListView.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/views/gamelist/IGameListView.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/views/GridGameListView.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/views/gamelist/ISimpleGameListView.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src/views/gamelist/GridGameListView.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/views/SystemListView.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/views/SystemListView.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/views/SystemView.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/views/SystemView.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/views/ViewController.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/views/ViewController.cpp
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
static const std::string LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
static const std::string LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
|
||||||
GuiFastSelect::GuiFastSelect(Window* window, GameListView* gamelist) : GuiComponent(window),
|
GuiFastSelect::GuiFastSelect(Window* window, IGameListView* gamelist) : GuiComponent(window),
|
||||||
mBackground(window), mSortText(window), mLetterText(window), mGameList(gamelist)
|
mBackground(window), mSortText(window), mLetterText(window), mGameList(gamelist)
|
||||||
{
|
{
|
||||||
setPosition(Renderer::getScreenWidth() * 0.2f, Renderer::getScreenHeight() * 0.2f);
|
setPosition(Renderer::getScreenWidth() * 0.2f, Renderer::getScreenHeight() * 0.2f);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../GuiComponent.h"
|
#include "../GuiComponent.h"
|
||||||
#include "../views/GameListView.h"
|
#include "../views/gamelist/IGameListView.h"
|
||||||
|
|
||||||
#include "NinePatchComponent.h"
|
#include "NinePatchComponent.h"
|
||||||
#include "TextComponent.h"
|
#include "TextComponent.h"
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
class GuiFastSelect : public GuiComponent
|
class GuiFastSelect : public GuiComponent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GuiFastSelect(Window* window, GameListView* gamelist);
|
GuiFastSelect(Window* window, IGameListView* gamelist);
|
||||||
|
|
||||||
bool input(InputConfig* config, Input input);
|
bool input(InputConfig* config, Input input);
|
||||||
void update(int deltaTime);
|
void update(int deltaTime);
|
||||||
|
@ -31,5 +31,5 @@ private:
|
||||||
TextComponent mSortText;
|
TextComponent mSortText;
|
||||||
TextComponent mLetterText;
|
TextComponent mLetterText;
|
||||||
|
|
||||||
GameListView* mGameList;
|
IGameListView* mGameList;
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,6 +24,7 @@ public:
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
void setCursor(const T& select);
|
void setCursor(const T& select);
|
||||||
|
void setCursor(typename const std::vector<Entry>::const_iterator& it);
|
||||||
|
|
||||||
inline const T& getSelected() const { return mEntries.at(mCursor).object; }
|
inline const T& getSelected() const { return mEntries.at(mCursor).object; }
|
||||||
inline const std::vector<Entry>& getList() const { return mEntries; }
|
inline const std::vector<Entry>& getList() const { return mEntries; }
|
||||||
|
@ -171,6 +172,14 @@ void ImageGridComponent<T>::setCursor(const T& obj)
|
||||||
LOG(LogError) << "Tried to set cursor to object we couldn't find";
|
LOG(LogError) << "Tried to set cursor to object we couldn't find";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void ImageGridComponent<T>::setCursor(typename const std::vector<Entry>::const_iterator& it)
|
||||||
|
{
|
||||||
|
assert(it != mEntries.end());
|
||||||
|
mCursor = it - mEntries.begin();
|
||||||
|
onCursorChanged(CURSOR_STOPPED);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void ImageGridComponent<T>::stopScrolling()
|
void ImageGridComponent<T>::stopScrolling()
|
||||||
{
|
{
|
||||||
|
|
|
@ -49,6 +49,7 @@ public:
|
||||||
inline const std::vector<ListRow>& getList() const { return mRowVector; }
|
inline const std::vector<ListRow>& getList() const { return mRowVector; }
|
||||||
|
|
||||||
void setCursor(const T& select);
|
void setCursor(const T& select);
|
||||||
|
void setCursor(typename const std::vector<ListRow>::const_iterator& it);
|
||||||
|
|
||||||
void stopScrolling();
|
void stopScrolling();
|
||||||
inline bool isScrolling() const { return mScrollDir != 0; }
|
inline bool isScrolling() const { return mScrollDir != 0; }
|
||||||
|
@ -375,6 +376,15 @@ void TextListComponent<T>::setCursor(const T& obj)
|
||||||
LOG(LogError) << "Tried to set cursor to object we couldn't find";
|
LOG(LogError) << "Tried to set cursor to object we couldn't find";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void TextListComponent<T>::setCursor(typename const std::vector<ListRow>::const_iterator& it)
|
||||||
|
{
|
||||||
|
assert(it != mRowVector.end());
|
||||||
|
mCursor = it - mRowVector.begin();
|
||||||
|
onCursorChanged(CURSOR_STOPPED);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void TextListComponent<T>::onCursorChanged(CursorState state)
|
void TextListComponent<T>::onCursorChanged(CursorState state)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,183 +0,0 @@
|
||||||
#include "BasicGameListView.h"
|
|
||||||
#include "ViewController.h"
|
|
||||||
#include "../Renderer.h"
|
|
||||||
#include "../Window.h"
|
|
||||||
#include "../ThemeData.h"
|
|
||||||
|
|
||||||
BasicGameListView::BasicGameListView(Window* window, FileData* root)
|
|
||||||
: GameListView(window, root),
|
|
||||||
mHeaderText(window), mHeaderImage(window), mBackground(window), mList(window)
|
|
||||||
{
|
|
||||||
mHeaderText.setText("Header");
|
|
||||||
mHeaderText.setSize(mSize.x(), 0);
|
|
||||||
mHeaderText.setPosition(0, 0);
|
|
||||||
mHeaderText.setCentered(true);
|
|
||||||
|
|
||||||
mHeaderImage.setResize(0, mSize.y() * 0.185f, false);
|
|
||||||
mHeaderImage.setOrigin(0.5f, 0.0f);
|
|
||||||
mHeaderImage.setPosition(mSize.x() / 2, 0);
|
|
||||||
|
|
||||||
mBackground.setResize(mSize.x(), mSize.y(), true);
|
|
||||||
|
|
||||||
mList.setSize(mSize.x(), mSize.y() * 0.8f);
|
|
||||||
mList.setPosition(0, mSize.y() * 0.2f);
|
|
||||||
|
|
||||||
populateList(root);
|
|
||||||
|
|
||||||
addChild(&mBackground);
|
|
||||||
addChild(&mList);
|
|
||||||
addChild(&mHeaderText);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BasicGameListView::onThemeChanged(const std::shared_ptr<ThemeData>& theme)
|
|
||||||
{
|
|
||||||
const ImageDef& bg = theme->getImage("backgroundImage");
|
|
||||||
mBackground.setTiling(bg.tile);
|
|
||||||
mBackground.setImage(bg.getTexture());
|
|
||||||
|
|
||||||
const ImageDef& hdr = theme->getImage("headerImage");
|
|
||||||
mHeaderImage.setTiling(hdr.tile);
|
|
||||||
mHeaderImage.setImage(hdr.getTexture());
|
|
||||||
|
|
||||||
if(mHeaderImage.hasImage())
|
|
||||||
{
|
|
||||||
removeChild(&mHeaderText);
|
|
||||||
addChild(&mHeaderImage);
|
|
||||||
}else{
|
|
||||||
addChild(&mHeaderText);
|
|
||||||
removeChild(&mHeaderImage);
|
|
||||||
}
|
|
||||||
|
|
||||||
mList.setTheme(theme);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BasicGameListView::onFileChanged(FileData* file, FileChangeType change)
|
|
||||||
{
|
|
||||||
// we don't care about metadata changes (since we don't display metadata),
|
|
||||||
// so we just ignore the FILE_METADATA_CHANGED case
|
|
||||||
|
|
||||||
// if it's immediately inside our current folder
|
|
||||||
if(file->getParent() == getCurrentFolder())
|
|
||||||
{
|
|
||||||
if(change == FILE_REMOVED)
|
|
||||||
{
|
|
||||||
mList.remove(file); // will automatically make sure cursor ends up in a "safe" place
|
|
||||||
}else if(change == FILE_ADDED)
|
|
||||||
{
|
|
||||||
FileData* cursor = getCursor();
|
|
||||||
populateList(cursor->getParent());
|
|
||||||
mList.setCursor(cursor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// the root file was sorted (so children were sorted too)
|
|
||||||
if(file == mRoot && change == FILE_SORTED)
|
|
||||||
{
|
|
||||||
FileData* cursor = getCursor();
|
|
||||||
populateList(cursor->getParent());
|
|
||||||
mList.setCursor(cursor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void buildHeader(FileData* from, std::stringstream& ss)
|
|
||||||
{
|
|
||||||
if(from->getParent())
|
|
||||||
{
|
|
||||||
buildHeader(from->getParent(), ss);
|
|
||||||
ss << " -> ";
|
|
||||||
}
|
|
||||||
|
|
||||||
ss << from->getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BasicGameListView::populateList(FileData* root)
|
|
||||||
{
|
|
||||||
mList.clear();
|
|
||||||
|
|
||||||
std::stringstream ss;
|
|
||||||
buildHeader(root, ss);
|
|
||||||
mHeaderText.setText(ss.str());
|
|
||||||
|
|
||||||
for(auto it = root->getChildren().begin(); it != root->getChildren().end(); it++)
|
|
||||||
{
|
|
||||||
mList.add((*it)->getName(), *it, ((*it)->getType() == FOLDER));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BasicGameListView::setCursor(FileData* cursor)
|
|
||||||
{
|
|
||||||
if(cursor->getParent() != getCursor()->getParent())
|
|
||||||
{
|
|
||||||
// Rebuild the folder stack
|
|
||||||
std::stack<FileData*> path;
|
|
||||||
FileData* cur = cursor;
|
|
||||||
while((cur = cur->getParent()) != mRoot)
|
|
||||||
path.push(cur);
|
|
||||||
|
|
||||||
while(!mCursorStack.empty())
|
|
||||||
mCursorStack.pop();
|
|
||||||
|
|
||||||
while(!path.empty()) // put back in reverse order (flip)
|
|
||||||
{
|
|
||||||
mCursorStack.push(path.top());
|
|
||||||
path.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
populateList(cursor->getParent());
|
|
||||||
}
|
|
||||||
|
|
||||||
mList.setCursor(cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BasicGameListView::input(InputConfig* config, Input input)
|
|
||||||
{
|
|
||||||
if(input.value != 0)
|
|
||||||
{
|
|
||||||
if(config->isMappedTo("a", input))
|
|
||||||
{
|
|
||||||
if(mList.getList().size() > 0)
|
|
||||||
{
|
|
||||||
FileData* cursor = getCursor();
|
|
||||||
if(cursor->getType() == GAME)
|
|
||||||
{
|
|
||||||
mWindow->getViewController()->launch(cursor);
|
|
||||||
}else{
|
|
||||||
// it's a folder
|
|
||||||
if(cursor->getChildren().size() > 0)
|
|
||||||
{
|
|
||||||
mCursorStack.push(cursor);
|
|
||||||
populateList(cursor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}else if(config->isMappedTo("b", input))
|
|
||||||
{
|
|
||||||
if(mCursorStack.size())
|
|
||||||
{
|
|
||||||
populateList(mCursorStack.top()->getParent());
|
|
||||||
mList.setCursor(mCursorStack.top());
|
|
||||||
mCursorStack.pop();
|
|
||||||
mTheme->playSound("backSound");
|
|
||||||
}else{
|
|
||||||
mList.stopScrolling();
|
|
||||||
mWindow->getViewController()->goToSystemSelect();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}else if(config->isMappedTo("right", input))
|
|
||||||
{
|
|
||||||
mList.stopScrolling();
|
|
||||||
mWindow->getViewController()->goToNextGameList();
|
|
||||||
return true;
|
|
||||||
}else if(config->isMappedTo("left", input))
|
|
||||||
{
|
|
||||||
mList.stopScrolling();
|
|
||||||
mWindow->getViewController()->goToPrevGameList();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return GameListView::input(config, input);
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "GameListView.h"
|
|
||||||
#include "../components/TextListComponent.h"
|
|
||||||
#include "../components/TextComponent.h"
|
|
||||||
#include "../components/ImageComponent.h"
|
|
||||||
|
|
||||||
class BasicGameListView : public GameListView
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
BasicGameListView(Window* window, FileData* root);
|
|
||||||
|
|
||||||
// Called when a FileData* is added, has its metadata changed, or is removed
|
|
||||||
virtual void onFileChanged(FileData* file, FileChangeType change);
|
|
||||||
|
|
||||||
virtual bool input(InputConfig* config, Input input) override;
|
|
||||||
|
|
||||||
virtual void onThemeChanged(const std::shared_ptr<ThemeData>& theme) override;
|
|
||||||
|
|
||||||
inline FileData* getCursor() { return mList.getSelected(); }
|
|
||||||
virtual void setCursor(FileData* file) override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void populateList(FileData* root);
|
|
||||||
|
|
||||||
TextComponent mHeaderText;
|
|
||||||
ImageComponent mHeaderImage;
|
|
||||||
ImageComponent mBackground;
|
|
||||||
TextListComponent<FileData*> mList;
|
|
||||||
|
|
||||||
inline FileData* getCurrentFolder() { return getCursor()->getParent(); }
|
|
||||||
|
|
||||||
std::stack<FileData*> mCursorStack;
|
|
||||||
};
|
|
|
@ -1,93 +0,0 @@
|
||||||
#include "GridGameListView.h"
|
|
||||||
#include "../ThemeData.h"
|
|
||||||
#include "../Window.h"
|
|
||||||
#include "ViewController.h"
|
|
||||||
|
|
||||||
GridGameListView::GridGameListView(Window* window, FileData* root) : GameListView(window, root),
|
|
||||||
mGrid(window), mBackground(window)
|
|
||||||
{
|
|
||||||
mBackground.setResize(mSize.x(), mSize.y(), true);
|
|
||||||
addChild(&mBackground);
|
|
||||||
|
|
||||||
mGrid.setPosition(0, mSize.y() * 0.2f);
|
|
||||||
mGrid.setSize(mSize.x(), mSize.y() * 0.8f);
|
|
||||||
addChild(&mGrid);
|
|
||||||
|
|
||||||
populateList(root);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GridGameListView::onFileChanged(FileData* file, FileChangeType change)
|
|
||||||
{
|
|
||||||
// fuck it, just completely repopulate always all the time
|
|
||||||
FileData* cursor = getCursor();
|
|
||||||
populateList(cursor->getParent());
|
|
||||||
mGrid.setCursor(cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GridGameListView::onThemeChanged(const std::shared_ptr<ThemeData>& theme)
|
|
||||||
{
|
|
||||||
mBackground.setImage(theme->getImage("backgroundImage").getTexture());
|
|
||||||
mBackground.setTiling(theme->getImage("backgroundImage").tile);
|
|
||||||
}
|
|
||||||
|
|
||||||
FileData* GridGameListView::getCursor()
|
|
||||||
{
|
|
||||||
return mGrid.getSelected();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GridGameListView::setCursor(FileData* file)
|
|
||||||
{
|
|
||||||
assert(file->getParent() == getCursor()->getParent()); // too lazy to implement right now
|
|
||||||
mGrid.setCursor(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GridGameListView::input(InputConfig* config, Input input)
|
|
||||||
{
|
|
||||||
if(input.value != 0)
|
|
||||||
{
|
|
||||||
if(config->isMappedTo("a", input))
|
|
||||||
{
|
|
||||||
if(mGrid.getList().size() > 0)
|
|
||||||
{
|
|
||||||
FileData* cursor = getCursor();
|
|
||||||
if(cursor->getType() == GAME)
|
|
||||||
{
|
|
||||||
mWindow->getViewController()->launch(cursor);
|
|
||||||
}else{
|
|
||||||
// it's a folder
|
|
||||||
if(cursor->getChildren().size() > 0)
|
|
||||||
{
|
|
||||||
mCursorStack.push(cursor);
|
|
||||||
populateList(cursor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}else if(config->isMappedTo("b", input))
|
|
||||||
{
|
|
||||||
if(mCursorStack.size())
|
|
||||||
{
|
|
||||||
populateList(mCursorStack.top()->getParent());
|
|
||||||
mGrid.setCursor(mCursorStack.top());
|
|
||||||
mCursorStack.pop();
|
|
||||||
mTheme->playSound("backSound");
|
|
||||||
}else{
|
|
||||||
mGrid.stopScrolling();
|
|
||||||
mWindow->getViewController()->goToSystemSelect();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return GameListView::input(config, input);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GridGameListView::populateList(FileData* root)
|
|
||||||
{
|
|
||||||
mGrid.clear();
|
|
||||||
for(auto it = root->getChildren().begin(); it != root->getChildren().end(); it++)
|
|
||||||
{
|
|
||||||
mGrid.add((*it)->getThumbnailPath(), *it);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "GameListView.h"
|
|
||||||
#include "../components/ImageGridComponent.h"
|
|
||||||
#include "../components/ImageComponent.h"
|
|
||||||
#include <stack>
|
|
||||||
|
|
||||||
class GridGameListView : public GameListView
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
GridGameListView(Window* window, FileData* root);
|
|
||||||
|
|
||||||
virtual void onFileChanged(FileData* file, FileChangeType change) override;
|
|
||||||
virtual void onThemeChanged(const std::shared_ptr<ThemeData>& theme) override;
|
|
||||||
|
|
||||||
FileData* getCursor() override;
|
|
||||||
void setCursor(FileData*) override;
|
|
||||||
|
|
||||||
virtual bool input(InputConfig* config, Input input) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void populateList(FileData* root);
|
|
||||||
|
|
||||||
ImageGridComponent<FileData*> mGrid;
|
|
||||||
ImageComponent mBackground;
|
|
||||||
|
|
||||||
std::stack<FileData*> mCursorStack;
|
|
||||||
};
|
|
|
@ -2,9 +2,9 @@
|
||||||
#include "../Log.h"
|
#include "../Log.h"
|
||||||
#include "../SystemData.h"
|
#include "../SystemData.h"
|
||||||
|
|
||||||
#include "BasicGameListView.h"
|
#include "gamelist/BasicGameListView.h"
|
||||||
#include "DetailedGameListView.h"
|
#include "gamelist/DetailedGameListView.h"
|
||||||
#include "GridGameListView.h"
|
#include "gamelist/GridGameListView.h"
|
||||||
#include "../components/GuiMenu.h"
|
#include "../components/GuiMenu.h"
|
||||||
#include "../animations/LaunchAnimation.h"
|
#include "../animations/LaunchAnimation.h"
|
||||||
#include "../animations/MoveCameraAnimation.h"
|
#include "../animations/MoveCameraAnimation.h"
|
||||||
|
@ -116,7 +116,7 @@ void ViewController::launch(FileData* game, Eigen::Vector3f center)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<GameListView> ViewController::getGameListView(SystemData* system)
|
std::shared_ptr<IGameListView> ViewController::getGameListView(SystemData* system)
|
||||||
{
|
{
|
||||||
//if we already made one, return that one
|
//if we already made one, return that one
|
||||||
auto exists = mGameListViews.find(system);
|
auto exists = mGameListViews.find(system);
|
||||||
|
@ -124,7 +124,7 @@ std::shared_ptr<GameListView> ViewController::getGameListView(SystemData* system
|
||||||
return exists->second;
|
return exists->second;
|
||||||
|
|
||||||
//if we didn't, make it, remember it, and return it
|
//if we didn't, make it, remember it, and return it
|
||||||
std::shared_ptr<GameListView> view;
|
std::shared_ptr<IGameListView> view;
|
||||||
|
|
||||||
if(system != NULL)
|
if(system != NULL)
|
||||||
{
|
{
|
||||||
|
@ -141,11 +141,11 @@ std::shared_ptr<GameListView> ViewController::getGameListView(SystemData* system
|
||||||
}
|
}
|
||||||
|
|
||||||
if(detailed)
|
if(detailed)
|
||||||
view = std::shared_ptr<GameListView>(new DetailedGameListView(mWindow, system->getRootFolder()));
|
view = std::shared_ptr<IGameListView>(new DetailedGameListView(mWindow, system->getRootFolder()));
|
||||||
else
|
else
|
||||||
view = std::shared_ptr<GameListView>(new BasicGameListView(mWindow, system->getRootFolder()));
|
view = std::shared_ptr<IGameListView>(new BasicGameListView(mWindow, system->getRootFolder()));
|
||||||
|
|
||||||
//view = std::shared_ptr<GameListView>(new GridGameListView(mWindow, system->getRootFolder()));
|
view = std::shared_ptr<IGameListView>(new GridGameListView(mWindow, system->getRootFolder()));
|
||||||
|
|
||||||
view->setTheme(system->getTheme());
|
view->setTheme(system->getTheme());
|
||||||
}else{
|
}else{
|
||||||
|
@ -240,3 +240,21 @@ void ViewController::preload()
|
||||||
getGameListView(*it);
|
getGameListView(*it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ViewController::reloadGameListView(IGameListView* view)
|
||||||
|
{
|
||||||
|
for(auto it = mGameListViews.begin(); it != mGameListViews.end(); it++)
|
||||||
|
{
|
||||||
|
if(it->second.get() == view)
|
||||||
|
{
|
||||||
|
SystemData* system = it->first;
|
||||||
|
FileData* cursor = view->getCursor();
|
||||||
|
mGameListViews.erase(it);
|
||||||
|
|
||||||
|
std::shared_ptr<IGameListView> newView = getGameListView(system);
|
||||||
|
newView->setCursor(cursor);
|
||||||
|
mCurrentView = newView;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "GameListView.h"
|
#include "gamelist/IGameListView.h"
|
||||||
#include "SystemListView.h"
|
#include "SystemListView.h"
|
||||||
|
|
||||||
class SystemData;
|
class SystemData;
|
||||||
|
@ -14,6 +14,10 @@ public:
|
||||||
// Caches things so there's no pauses during transitions.
|
// Caches things so there's no pauses during transitions.
|
||||||
void preload();
|
void preload();
|
||||||
|
|
||||||
|
// If a basic view detected a metadata change, it can request to recreate
|
||||||
|
// the current gamelist view (as it may change to be detailed).
|
||||||
|
void reloadGameListView(IGameListView* gamelist);
|
||||||
|
|
||||||
// Navigation.
|
// Navigation.
|
||||||
void goToNextGameList();
|
void goToNextGameList();
|
||||||
void goToPrevGameList();
|
void goToPrevGameList();
|
||||||
|
@ -55,11 +59,11 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void playViewTransition();
|
void playViewTransition();
|
||||||
std::shared_ptr<GameListView> getGameListView(SystemData* system);
|
std::shared_ptr<IGameListView> getGameListView(SystemData* system);
|
||||||
std::shared_ptr<SystemListView> getSystemListView();
|
std::shared_ptr<SystemListView> getSystemListView();
|
||||||
|
|
||||||
std::shared_ptr<GuiComponent> mCurrentView;
|
std::shared_ptr<GuiComponent> mCurrentView;
|
||||||
std::map< SystemData*, std::shared_ptr<GameListView> > mGameListViews;
|
std::map< SystemData*, std::shared_ptr<IGameListView> > mGameListViews;
|
||||||
std::shared_ptr<SystemListView> mSystemListView;
|
std::shared_ptr<SystemListView> mSystemListView;
|
||||||
|
|
||||||
Eigen::Affine3f mCamera;
|
Eigen::Affine3f mCamera;
|
||||||
|
|
71
src/views/gamelist/BasicGameListView.cpp
Normal file
71
src/views/gamelist/BasicGameListView.cpp
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
#include "BasicGameListView.h"
|
||||||
|
#include "../ViewController.h"
|
||||||
|
#include "../../Renderer.h"
|
||||||
|
#include "../../Window.h"
|
||||||
|
#include "../../ThemeData.h"
|
||||||
|
#include "../../SystemData.h"
|
||||||
|
|
||||||
|
BasicGameListView::BasicGameListView(Window* window, FileData* root)
|
||||||
|
: ISimpleGameListView(window, root), mList(window)
|
||||||
|
{
|
||||||
|
mList.setSize(mSize.x(), mSize.y() * 0.8f);
|
||||||
|
mList.setPosition(0, mSize.y() * 0.2f);
|
||||||
|
addChild(&mList);
|
||||||
|
|
||||||
|
populateList(root->getChildren());
|
||||||
|
}
|
||||||
|
|
||||||
|
void BasicGameListView::onThemeChanged(const std::shared_ptr<ThemeData>& theme)
|
||||||
|
{
|
||||||
|
ISimpleGameListView::onThemeChanged(theme);
|
||||||
|
mList.setTheme(theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BasicGameListView::onFileChanged(FileData* file, FileChangeType change)
|
||||||
|
{
|
||||||
|
if(change == FILE_METADATA_CHANGED)
|
||||||
|
{
|
||||||
|
// might switch to a detailed view
|
||||||
|
mWindow->getViewController()->reloadGameListView(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ISimpleGameListView::onFileChanged(file, change);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BasicGameListView::populateList(const std::vector<FileData*>& files)
|
||||||
|
{
|
||||||
|
mList.clear();
|
||||||
|
|
||||||
|
mHeaderText.setText(files.at(0)->getSystem()->getFullName());
|
||||||
|
|
||||||
|
for(auto it = files.begin(); it != files.end(); it++)
|
||||||
|
{
|
||||||
|
mList.add((*it)->getName(), *it, ((*it)->getType() == FOLDER));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FileData* BasicGameListView::getCursor()
|
||||||
|
{
|
||||||
|
return mList.getSelected();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BasicGameListView::setCursor(FileData* cursor)
|
||||||
|
{
|
||||||
|
typedef TextListComponent<FileData*>::ListRow Row;
|
||||||
|
const std::vector<Row>& list = mList.getList();
|
||||||
|
auto found = std::find_if(list.begin(), list.end(), [&](const Row& row) { return (row.object == cursor); });
|
||||||
|
|
||||||
|
if(found != list.end())
|
||||||
|
{
|
||||||
|
mList.setCursor(found);
|
||||||
|
}else{
|
||||||
|
populateList(cursor->getParent()->getChildren());
|
||||||
|
mList.setCursor(cursor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BasicGameListView::launch(FileData* game)
|
||||||
|
{
|
||||||
|
mWindow->getViewController()->launch(game);
|
||||||
|
}
|
24
src/views/gamelist/BasicGameListView.h
Normal file
24
src/views/gamelist/BasicGameListView.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ISimpleGameListView.h"
|
||||||
|
#include "../../components/TextListComponent.h"
|
||||||
|
|
||||||
|
class BasicGameListView : public ISimpleGameListView
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BasicGameListView(Window* window, FileData* root);
|
||||||
|
|
||||||
|
// Called when a FileData* is added, has its metadata changed, or is removed
|
||||||
|
virtual void onFileChanged(FileData* file, FileChangeType change);
|
||||||
|
|
||||||
|
virtual void onThemeChanged(const std::shared_ptr<ThemeData>& theme);
|
||||||
|
|
||||||
|
virtual FileData* getCursor() override;
|
||||||
|
virtual void setCursor(FileData* file) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void populateList(const std::vector<FileData*>& files) override;
|
||||||
|
virtual void launch(FileData* game) override;
|
||||||
|
|
||||||
|
TextListComponent<FileData*> mList;
|
||||||
|
};
|
|
@ -1,4 +1,6 @@
|
||||||
#include "DetailedGameListView.h"
|
#include "DetailedGameListView.h"
|
||||||
|
#include "../../Window.h"
|
||||||
|
#include "../ViewController.h"
|
||||||
|
|
||||||
DetailedGameListView::DetailedGameListView(Window* window, FileData* root) :
|
DetailedGameListView::DetailedGameListView(Window* window, FileData* root) :
|
||||||
BasicGameListView(window, root),
|
BasicGameListView(window, root),
|
||||||
|
@ -75,10 +77,11 @@ void DetailedGameListView::updateInfoPanel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DetailedGameListView::onFileChanged(FileData* file, FileChangeType type)
|
void DetailedGameListView::launch(FileData* game)
|
||||||
{
|
{
|
||||||
BasicGameListView::onFileChanged(file, type);
|
Eigen::Vector3f target(Renderer::getScreenWidth() / 2.0f, Renderer::getScreenHeight() / 2.0f, 0);
|
||||||
|
if(mImage.hasImage())
|
||||||
|
target = mImage.getPosition();
|
||||||
|
|
||||||
if(type == FILE_METADATA_CHANGED && file == getCursor())
|
mWindow->getViewController()->launch(game, target);
|
||||||
updateInfoPanel();
|
|
||||||
}
|
}
|
|
@ -1,9 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "BasicGameListView.h"
|
#include "BasicGameListView.h"
|
||||||
#include "../components/ImageComponent.h"
|
#include "../../components/ScrollableContainer.h"
|
||||||
#include "../components/TextComponent.h"
|
|
||||||
#include "../components/ScrollableContainer.h"
|
|
||||||
|
|
||||||
class DetailedGameListView : public BasicGameListView
|
class DetailedGameListView : public BasicGameListView
|
||||||
{
|
{
|
||||||
|
@ -12,7 +10,8 @@ public:
|
||||||
|
|
||||||
virtual void onThemeChanged(const std::shared_ptr<ThemeData>& theme) override;
|
virtual void onThemeChanged(const std::shared_ptr<ThemeData>& theme) override;
|
||||||
|
|
||||||
virtual void onFileChanged(FileData* file, FileChangeType change);
|
protected:
|
||||||
|
virtual void launch(FileData* game) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateInfoPanel();
|
void updateInfoPanel();
|
||||||
|
@ -24,4 +23,3 @@ private:
|
||||||
ScrollableContainer mDescContainer;
|
ScrollableContainer mDescContainer;
|
||||||
TextComponent mDescription;
|
TextComponent mDescription;
|
||||||
};
|
};
|
||||||
|
|
56
src/views/gamelist/GridGameListView.cpp
Normal file
56
src/views/gamelist/GridGameListView.cpp
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
#include "GridGameListView.h"
|
||||||
|
#include "../../ThemeData.h"
|
||||||
|
#include "../../Window.h"
|
||||||
|
#include "../ViewController.h"
|
||||||
|
|
||||||
|
GridGameListView::GridGameListView(Window* window, FileData* root) : ISimpleGameListView(window, root),
|
||||||
|
mGrid(window)
|
||||||
|
{
|
||||||
|
mGrid.setPosition(0, mSize.y() * 0.2f);
|
||||||
|
mGrid.setSize(mSize.x(), mSize.y() * 0.8f);
|
||||||
|
addChild(&mGrid);
|
||||||
|
|
||||||
|
populateList(root->getChildren());
|
||||||
|
}
|
||||||
|
|
||||||
|
FileData* GridGameListView::getCursor()
|
||||||
|
{
|
||||||
|
return mGrid.getSelected();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridGameListView::setCursor(FileData* file)
|
||||||
|
{
|
||||||
|
typedef ImageGridComponent<FileData*>::Entry Entry;
|
||||||
|
auto& list = mGrid.getList();
|
||||||
|
auto found = std::find_if(list.begin(), list.end(), [&] (const Entry& e) { return (e.object == file); });
|
||||||
|
|
||||||
|
if(found != list.end())
|
||||||
|
{
|
||||||
|
mGrid.setCursor(found);
|
||||||
|
}else{
|
||||||
|
populateList(file->getParent()->getChildren());
|
||||||
|
mGrid.setCursor(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GridGameListView::input(InputConfig* config, Input input)
|
||||||
|
{
|
||||||
|
if(config->isMappedTo("left", input) || config->isMappedTo("right", input))
|
||||||
|
return GuiComponent::input(config, input);
|
||||||
|
|
||||||
|
return ISimpleGameListView::input(config, input);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridGameListView::populateList(const std::vector<FileData*>& files)
|
||||||
|
{
|
||||||
|
mGrid.clear();
|
||||||
|
for(auto it = files.begin(); it != files.end(); it++)
|
||||||
|
{
|
||||||
|
mGrid.add((*it)->getThumbnailPath(), *it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridGameListView::launch(FileData* game)
|
||||||
|
{
|
||||||
|
mWindow->getViewController()->launch(game);
|
||||||
|
}
|
25
src/views/gamelist/GridGameListView.h
Normal file
25
src/views/gamelist/GridGameListView.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ISimpleGameListView.h"
|
||||||
|
#include "../../components/ImageGridComponent.h"
|
||||||
|
#include "../../components/ImageComponent.h"
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
|
class GridGameListView : public ISimpleGameListView
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GridGameListView(Window* window, FileData* root);
|
||||||
|
|
||||||
|
//virtual void onThemeChanged(const std::shared_ptr<ThemeData>& theme) override;
|
||||||
|
|
||||||
|
virtual FileData* getCursor() override;
|
||||||
|
virtual void setCursor(FileData*) override;
|
||||||
|
|
||||||
|
virtual bool input(InputConfig* config, Input input) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void populateList(const std::vector<FileData*>& files) override;
|
||||||
|
virtual void launch(FileData* game) override;
|
||||||
|
|
||||||
|
ImageGridComponent<FileData*> mGrid;
|
||||||
|
};
|
|
@ -1,11 +1,11 @@
|
||||||
#include "GameListView.h"
|
#include "IGameListView.h"
|
||||||
#include "../Window.h"
|
#include "../../Window.h"
|
||||||
#include "../components/GuiMetaDataEd.h"
|
#include "../../components/GuiMetaDataEd.h"
|
||||||
#include "../components/GuiMenu.h"
|
#include "../../components/GuiMenu.h"
|
||||||
#include "../components/GuiFastSelect.h"
|
#include "../../components/GuiFastSelect.h"
|
||||||
#include "ViewController.h"
|
#include "../ViewController.h"
|
||||||
|
|
||||||
bool GameListView::input(InputConfig* config, Input input)
|
bool IGameListView::input(InputConfig* config, Input input)
|
||||||
{
|
{
|
||||||
if(config->getDeviceId() == DEVICE_KEYBOARD && input.id == SDLK_F3 && input.value != 0)
|
if(config->getDeviceId() == DEVICE_KEYBOARD && input.id == SDLK_F3 && input.value != 0)
|
||||||
{
|
{
|
||||||
|
@ -15,7 +15,7 @@ bool GameListView::input(InputConfig* config, Input input)
|
||||||
p.game = file;
|
p.game = file;
|
||||||
p.system = file->getSystem();
|
p.system = file->getSystem();
|
||||||
mWindow->pushGui(new GuiMetaDataEd(mWindow, &file->metadata, file->metadata.getMDD(), p, file->getPath().filename().string(),
|
mWindow->pushGui(new GuiMetaDataEd(mWindow, &file->metadata, file->metadata.getMDD(), p, file->getPath().filename().string(),
|
||||||
std::bind(&GameListView::onFileChanged, this, file, FILE_METADATA_CHANGED), [file, this] {
|
std::bind(&IGameListView::onFileChanged, this, file, FILE_METADATA_CHANGED), [file, this] {
|
||||||
boost::filesystem::remove(file->getPath()); //actually delete the file on the filesystem
|
boost::filesystem::remove(file->getPath()); //actually delete the file on the filesystem
|
||||||
file->getParent()->removeChild(file); //unlink it so list repopulations triggered from onFileChanged won't see it
|
file->getParent()->removeChild(file); //unlink it so list repopulations triggered from onFileChanged won't see it
|
||||||
onFileChanged(file, FILE_REMOVED); //tell the view
|
onFileChanged(file, FILE_REMOVED); //tell the view
|
||||||
|
@ -33,7 +33,7 @@ bool GameListView::input(InputConfig* config, Input input)
|
||||||
return GuiComponent::input(config, input);
|
return GuiComponent::input(config, input);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameListView::setTheme(const std::shared_ptr<ThemeData>& theme)
|
void IGameListView::setTheme(const std::shared_ptr<ThemeData>& theme)
|
||||||
{
|
{
|
||||||
mTheme = theme;
|
mTheme = theme;
|
||||||
onThemeChanged(theme);
|
onThemeChanged(theme);
|
|
@ -1,24 +1,24 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../FileData.h"
|
#include "../../FileData.h"
|
||||||
#include "../Renderer.h"
|
#include "../../Renderer.h"
|
||||||
|
|
||||||
class Window;
|
class Window;
|
||||||
class GuiComponent;
|
class GuiComponent;
|
||||||
class FileData;
|
class FileData;
|
||||||
class ThemeData;
|
class ThemeData;
|
||||||
|
|
||||||
//GameListView needs to know:
|
//IGameListView needs to know:
|
||||||
// What theme data to use
|
// What theme data to use
|
||||||
// The root FileData for the tree it should explore
|
// The root FileData for the tree it should explore
|
||||||
|
|
||||||
class GameListView : public GuiComponent
|
class IGameListView : public GuiComponent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GameListView(Window* window, FileData* root) : GuiComponent(window), mRoot(root)
|
IGameListView(Window* window, FileData* root) : GuiComponent(window), mRoot(root)
|
||||||
{ setSize((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight()); }
|
{ setSize((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight()); }
|
||||||
|
|
||||||
virtual ~GameListView() {}
|
virtual ~IGameListView() {}
|
||||||
|
|
||||||
// Called when a new file is added, a file is removed, a file's metadata changes, or a file's children are sorted.
|
// Called when a new file is added, a file is removed, a file's metadata changes, or a file's children are sorted.
|
||||||
// NOTE: FILE_SORTED is only reported for the topmost FileData, where the sort started.
|
// NOTE: FILE_SORTED is only reported for the topmost FileData, where the sort started.
|
101
src/views/gamelist/ISimpleGameListView.cpp
Normal file
101
src/views/gamelist/ISimpleGameListView.cpp
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
#include "ISimpleGameListView.h"
|
||||||
|
#include "../../ThemeData.h"
|
||||||
|
#include "../../Window.h"
|
||||||
|
#include "../ViewController.h"
|
||||||
|
|
||||||
|
ISimpleGameListView::ISimpleGameListView(Window* window, FileData* root) : IGameListView(window, root),
|
||||||
|
mHeaderText(window), mHeaderImage(window), mBackground(window)
|
||||||
|
{
|
||||||
|
mHeaderText.setText("Header");
|
||||||
|
mHeaderText.setSize(mSize.x(), 0);
|
||||||
|
mHeaderText.setPosition(0, 0);
|
||||||
|
mHeaderText.setCentered(true);
|
||||||
|
|
||||||
|
mHeaderImage.setResize(0, mSize.y() * 0.185f, false);
|
||||||
|
mHeaderImage.setOrigin(0.5f, 0.0f);
|
||||||
|
mHeaderImage.setPosition(mSize.x() / 2, 0);
|
||||||
|
|
||||||
|
mBackground.setResize(mSize.x(), mSize.y(), true);
|
||||||
|
|
||||||
|
addChild(&mHeaderText);
|
||||||
|
addChild(&mBackground);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ISimpleGameListView::onThemeChanged(const std::shared_ptr<ThemeData>& theme)
|
||||||
|
{
|
||||||
|
const ImageDef& bg = theme->getImage("backgroundImage");
|
||||||
|
mBackground.setTiling(bg.tile);
|
||||||
|
mBackground.setImage(bg.getTexture());
|
||||||
|
|
||||||
|
const ImageDef& hdr = theme->getImage("headerImage");
|
||||||
|
mHeaderImage.setTiling(hdr.tile);
|
||||||
|
mHeaderImage.setImage(hdr.getTexture());
|
||||||
|
|
||||||
|
if(mHeaderImage.hasImage())
|
||||||
|
{
|
||||||
|
removeChild(&mHeaderText);
|
||||||
|
addChild(&mHeaderImage);
|
||||||
|
}else{
|
||||||
|
addChild(&mHeaderText);
|
||||||
|
removeChild(&mHeaderImage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ISimpleGameListView::onFileChanged(FileData* file, FileChangeType change)
|
||||||
|
{
|
||||||
|
// we could be tricky here to be efficient;
|
||||||
|
// but this shouldn't happen very often so we'll just always repopulate
|
||||||
|
FileData* cursor = getCursor();
|
||||||
|
populateList(cursor->getParent()->getChildren());
|
||||||
|
setCursor(cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ISimpleGameListView::input(InputConfig* config, Input input)
|
||||||
|
{
|
||||||
|
if(input.value != 0)
|
||||||
|
{
|
||||||
|
if(config->isMappedTo("a", input))
|
||||||
|
{
|
||||||
|
FileData* cursor = getCursor();
|
||||||
|
if(cursor->getType() == GAME)
|
||||||
|
{
|
||||||
|
launch(cursor);
|
||||||
|
}else{
|
||||||
|
// it's a folder
|
||||||
|
if(cursor->getChildren().size() > 0)
|
||||||
|
{
|
||||||
|
mCursorStack.push(cursor);
|
||||||
|
populateList(cursor->getChildren());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}else if(config->isMappedTo("b", input))
|
||||||
|
{
|
||||||
|
if(mCursorStack.size())
|
||||||
|
{
|
||||||
|
populateList(mCursorStack.top()->getParent()->getChildren());
|
||||||
|
setCursor(mCursorStack.top());
|
||||||
|
mCursorStack.pop();
|
||||||
|
getTheme()->playSound("backSound");
|
||||||
|
}else{
|
||||||
|
onFocusLost();
|
||||||
|
mWindow->getViewController()->goToSystemSelect();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}else if(config->isMappedTo("right", input))
|
||||||
|
{
|
||||||
|
onFocusLost();
|
||||||
|
mWindow->getViewController()->goToNextGameList();
|
||||||
|
return true;
|
||||||
|
}else if(config->isMappedTo("left", input))
|
||||||
|
{
|
||||||
|
onFocusLost();
|
||||||
|
mWindow->getViewController()->goToPrevGameList();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return IGameListView::input(config, input);
|
||||||
|
}
|
36
src/views/gamelist/ISimpleGameListView.h
Normal file
36
src/views/gamelist/ISimpleGameListView.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "IGameListView.h"
|
||||||
|
|
||||||
|
#include "../../components/TextComponent.h"
|
||||||
|
#include "../../components/ImageComponent.h"
|
||||||
|
|
||||||
|
class ISimpleGameListView : public IGameListView
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ISimpleGameListView(Window* window, FileData* root);
|
||||||
|
virtual ~ISimpleGameListView() {}
|
||||||
|
|
||||||
|
// Called when a new file is added, a file is removed, a file's metadata changes, or a file's children are sorted.
|
||||||
|
// NOTE: FILE_SORTED is only reported for the topmost FileData, where the sort started.
|
||||||
|
// Since sorts are recursive, that FileData's children probably changed too.
|
||||||
|
virtual void onFileChanged(FileData* file, FileChangeType change);
|
||||||
|
|
||||||
|
// Called whenever the theme changes.
|
||||||
|
virtual void onThemeChanged(const std::shared_ptr<ThemeData>& theme);
|
||||||
|
|
||||||
|
virtual FileData* getCursor() = 0;
|
||||||
|
virtual void setCursor(FileData*) = 0;
|
||||||
|
|
||||||
|
virtual bool input(InputConfig* config, Input input) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void populateList(const std::vector<FileData*>& files) = 0;
|
||||||
|
virtual void launch(FileData* game) = 0;
|
||||||
|
|
||||||
|
TextComponent mHeaderText;
|
||||||
|
ImageComponent mHeaderImage;
|
||||||
|
ImageComponent mBackground;
|
||||||
|
|
||||||
|
std::stack<FileData*> mCursorStack;
|
||||||
|
};
|
Loading…
Reference in a new issue