mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-02-16 20:15:38 +00:00
Added GridGameListView.
Currently no way to enable it and no way to switch systems with it.
This commit is contained in:
parent
25a4c8a2e5
commit
9875a59549
|
@ -164,6 +164,7 @@ set(ES_HEADERS
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ComponentListComponent.h
|
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ComponentListComponent.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/DateTimeComponent.h
|
${CMAKE_CURRENT_SOURCE_DIR}/src/components/DateTimeComponent.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ImageComponent.h
|
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ImageComponent.h
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src/components/ImageGridComponent.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/NinePatchComponent.h
|
${CMAKE_CURRENT_SOURCE_DIR}/src/components/NinePatchComponent.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/OptionListComponent.h
|
${CMAKE_CURRENT_SOURCE_DIR}/src/components/OptionListComponent.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/components/RatingComponent.h
|
${CMAKE_CURRENT_SOURCE_DIR}/src/components/RatingComponent.h
|
||||||
|
@ -195,6 +196,7 @@ set(ES_HEADERS
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/views/BasicGameListView.h
|
${CMAKE_CURRENT_SOURCE_DIR}/src/views/BasicGameListView.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/views/DetailedGameListView.h
|
${CMAKE_CURRENT_SOURCE_DIR}/src/views/DetailedGameListView.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/views/GameListView.h
|
${CMAKE_CURRENT_SOURCE_DIR}/src/views/GameListView.h
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src/views/GridGameListView.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/views/ViewController.h
|
${CMAKE_CURRENT_SOURCE_DIR}/src/views/ViewController.h
|
||||||
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/resources/Font.h
|
${CMAKE_CURRENT_SOURCE_DIR}/src/resources/Font.h
|
||||||
|
@ -264,6 +266,7 @@ set(ES_SOURCES
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/views/BasicGameListView.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/views/BasicGameListView.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/views/DetailedGameListView.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/views/DetailedGameListView.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/views/GameListView.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/views/GameListView.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src/views/GridGameListView.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/views/ViewController.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/views/ViewController.cpp
|
||||||
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/data/ResourceUtil.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/data/ResourceUtil.cpp
|
||||||
|
|
|
@ -123,6 +123,7 @@ void GuiGameScraper::onSearchDone(std::vector<MetaDataList> results)
|
||||||
|
|
||||||
mList.resetCursor();
|
mList.resetCursor();
|
||||||
mList.moveCursor(Eigen::Vector2i(0, 1)); //move cursor to first game if there is one
|
mList.moveCursor(Eigen::Vector2i(0, 1)); //move cursor to first game if there is one
|
||||||
|
updateInfoPane();
|
||||||
}
|
}
|
||||||
|
|
||||||
int GuiGameScraper::getSelectedIndex()
|
int GuiGameScraper::getSelectedIndex()
|
||||||
|
@ -161,22 +162,7 @@ bool GuiGameScraper::input(InputConfig* config, Input input)
|
||||||
|
|
||||||
if(config->isMappedTo("up", input) || config->isMappedTo("down", input) && input.value != 0)
|
if(config->isMappedTo("up", input) || config->isMappedTo("down", input) && input.value != 0)
|
||||||
{
|
{
|
||||||
//update game info pane
|
updateInfoPane();
|
||||||
int i = getSelectedIndex();
|
|
||||||
if(i != -1)
|
|
||||||
{
|
|
||||||
mResultName.setText(mScraperResults.at(i).get("name"));
|
|
||||||
mResultDesc.setText(mScraperResults.at(i).get("desc"));
|
|
||||||
mResultInfo.setScrollPos(Eigen::Vector2d(0, 0));
|
|
||||||
mResultInfo.resetAutoScrollTimer();
|
|
||||||
|
|
||||||
std::string thumb = mScraperResults.at(i).get("thumbnail");
|
|
||||||
mResultThumbnail.setImage("");
|
|
||||||
if(!thumb.empty())
|
|
||||||
mThumbnailReq = std::unique_ptr<HttpReq>(new HttpReq(thumb));
|
|
||||||
else
|
|
||||||
mThumbnailReq.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//stopped editing
|
//stopped editing
|
||||||
|
@ -189,6 +175,25 @@ bool GuiGameScraper::input(InputConfig* config, Input input)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GuiGameScraper::updateInfoPane()
|
||||||
|
{
|
||||||
|
int i = getSelectedIndex();
|
||||||
|
if(i != -1)
|
||||||
|
{
|
||||||
|
mResultName.setText(mScraperResults.at(i).get("name"));
|
||||||
|
mResultDesc.setText(mScraperResults.at(i).get("desc"));
|
||||||
|
mResultInfo.setScrollPos(Eigen::Vector2d(0, 0));
|
||||||
|
mResultInfo.resetAutoScrollTimer();
|
||||||
|
|
||||||
|
std::string thumb = mScraperResults.at(i).get("thumbnail");
|
||||||
|
mResultThumbnail.setImage("");
|
||||||
|
if(!thumb.empty())
|
||||||
|
mThumbnailReq = std::unique_ptr<HttpReq>(new HttpReq(thumb));
|
||||||
|
else
|
||||||
|
mThumbnailReq.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GuiGameScraper::update(int deltaTime)
|
void GuiGameScraper::update(int deltaTime)
|
||||||
{
|
{
|
||||||
if(mThumbnailReq && mThumbnailReq->status() != HttpReq::REQ_IN_PROGRESS)
|
if(mThumbnailReq && mThumbnailReq->status() != HttpReq::REQ_IN_PROGRESS)
|
||||||
|
|
|
@ -25,6 +25,7 @@ public:
|
||||||
private:
|
private:
|
||||||
int getSelectedIndex();
|
int getSelectedIndex();
|
||||||
void onSearchDone(std::vector<MetaDataList> results);
|
void onSearchDone(std::vector<MetaDataList> results);
|
||||||
|
void updateInfoPane();
|
||||||
void updateThumbnail();
|
void updateThumbnail();
|
||||||
|
|
||||||
ComponentListComponent mList;
|
ComponentListComponent mList;
|
||||||
|
|
360
src/components/ImageGridComponent.h
Normal file
360
src/components/ImageGridComponent.h
Normal file
|
@ -0,0 +1,360 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../GuiComponent.h"
|
||||||
|
#include "../components/ImageComponent.h"
|
||||||
|
#include "../Log.h"
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class ImageGridComponent : public GuiComponent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ImageGridComponent(Window* window);
|
||||||
|
|
||||||
|
struct Entry
|
||||||
|
{
|
||||||
|
std::shared_ptr<TextureResource> texture;
|
||||||
|
T object;
|
||||||
|
|
||||||
|
Entry() {}
|
||||||
|
Entry(std::shared_ptr<TextureResource> t, const T& o) : texture(t), object(o) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
void add(const std::string& imagePath, const T& obj);
|
||||||
|
void remove(const T& obj);
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
void setCursor(const T& select);
|
||||||
|
|
||||||
|
inline const T& getSelected() const { return mEntries.at(mCursor).object; }
|
||||||
|
inline const std::vector<Entry>& getList() const { return mEntries; }
|
||||||
|
|
||||||
|
enum CursorState {
|
||||||
|
CURSOR_STOPPED,
|
||||||
|
CURSOR_SCROLLING
|
||||||
|
};
|
||||||
|
|
||||||
|
void stopScrolling();
|
||||||
|
|
||||||
|
void onSizeChanged() override;
|
||||||
|
|
||||||
|
bool input(InputConfig* config, Input input) override;
|
||||||
|
void update(int deltaTime) override;
|
||||||
|
void render(const Eigen::Affine3f& parentTrans) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Eigen::Vector2f getSquareSize(std::shared_ptr<TextureResource> tex = nullptr) const
|
||||||
|
{
|
||||||
|
Eigen::Vector2f aspect(1, 1);
|
||||||
|
|
||||||
|
if(tex)
|
||||||
|
{
|
||||||
|
const Eigen::Vector2i& texSize = tex->getSize();
|
||||||
|
|
||||||
|
if(texSize.x() > texSize.y())
|
||||||
|
aspect[0] = (float)texSize.x() / texSize.y();
|
||||||
|
else
|
||||||
|
aspect[1] = (float)texSize.y() / texSize.x();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Eigen::Vector2f(156 * aspect.x(), 156 * aspect.y());
|
||||||
|
};
|
||||||
|
|
||||||
|
Eigen::Vector2f getMaxSquareSize() const
|
||||||
|
{
|
||||||
|
Eigen::Vector2f squareSize(32, 32);
|
||||||
|
|
||||||
|
// calc biggest square size
|
||||||
|
for(auto it = mEntries.begin(); it != mEntries.end(); it++)
|
||||||
|
{
|
||||||
|
Eigen::Vector2f chkSize = getSquareSize(it->texture);
|
||||||
|
if(chkSize.x() > squareSize.x())
|
||||||
|
squareSize[0] = chkSize[0];
|
||||||
|
if(chkSize.y() > squareSize.y())
|
||||||
|
squareSize[1] = chkSize[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return squareSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
Eigen::Vector2i getGridSize() const
|
||||||
|
{
|
||||||
|
Eigen::Vector2f squareSize = getMaxSquareSize();
|
||||||
|
Eigen::Vector2i gridSize(mSize.x() / (squareSize.x() + getPadding().x()), mSize.y() / (squareSize.y() + getPadding().y()));
|
||||||
|
return gridSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
Eigen::Vector2f getPadding() const { return Eigen::Vector2f(24, 24); }
|
||||||
|
|
||||||
|
void buildImages();
|
||||||
|
void updateImages();
|
||||||
|
|
||||||
|
static const int SCROLL_DELAY = 507;
|
||||||
|
static const int SCROLL_TIME = 150;
|
||||||
|
|
||||||
|
void setScrollDir(Eigen::Vector2i dir);
|
||||||
|
void scroll();
|
||||||
|
void onCursorChanged(CursorState state);
|
||||||
|
|
||||||
|
int mCursor;
|
||||||
|
|
||||||
|
Eigen::Vector2i mScrollDir;
|
||||||
|
int mScrollAccumulator;
|
||||||
|
|
||||||
|
bool mEntriesDirty;
|
||||||
|
|
||||||
|
std::vector<Entry> mEntries;
|
||||||
|
std::vector<ImageComponent> mImages;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ImageGridComponent<T>::ImageGridComponent(Window* window) : GuiComponent(window)
|
||||||
|
{
|
||||||
|
mEntriesDirty = true;
|
||||||
|
mCursor = 0;
|
||||||
|
mScrollDir << 0, 0;
|
||||||
|
mScrollAccumulator = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void ImageGridComponent<T>::add(const std::string& imagePath, const T& obj)
|
||||||
|
{
|
||||||
|
Entry e(ResourceManager::getInstance()->fileExists(imagePath) ? TextureResource::get(imagePath) : TextureResource::get(":/button.png"), obj);
|
||||||
|
mEntries.push_back(e);
|
||||||
|
mEntriesDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void ImageGridComponent<T>::remove(const T& obj)
|
||||||
|
{
|
||||||
|
for(auto it = mEntries.begin(); it != mEntries.end(); it++)
|
||||||
|
{
|
||||||
|
if((*it).object == obj)
|
||||||
|
{
|
||||||
|
if(mCursor > 0 && it - mRowVector.begin() >= mCursor)
|
||||||
|
{
|
||||||
|
mCursor--;
|
||||||
|
onCursorChanged(CURSOR_STOPPED);
|
||||||
|
}
|
||||||
|
|
||||||
|
mEntriesDirty = true;
|
||||||
|
mEntries.erase(it);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG(LogError) << "Tried to remove an object we couldn't find";
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void ImageGridComponent<T>::clear()
|
||||||
|
{
|
||||||
|
mEntries.clear();
|
||||||
|
mCursor = 0;
|
||||||
|
mScrollDir << 0, 0;
|
||||||
|
onCursorChanged(CURSOR_STOPPED);
|
||||||
|
mEntriesDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void ImageGridComponent<T>::setCursor(const T& obj)
|
||||||
|
{
|
||||||
|
for(auto it = mEntries.begin(); it != mEntries.end(); it++)
|
||||||
|
{
|
||||||
|
if((*it).object == obj)
|
||||||
|
{
|
||||||
|
mCursor = it - mEntries.begin();
|
||||||
|
onCursorChanged(CURSOR_STOPPED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG(LogError) << "Tried to set cursor to object we couldn't find";
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void ImageGridComponent<T>::stopScrolling()
|
||||||
|
{
|
||||||
|
mScrollDir = Eigen::Vector2i::Zero();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void ImageGridComponent<T>::scroll()
|
||||||
|
{
|
||||||
|
if(mEntries.size() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
Eigen::Vector2i size = getGridSize();
|
||||||
|
|
||||||
|
offset += mScrollDir.x();
|
||||||
|
offset += mScrollDir.y() * size.x();
|
||||||
|
|
||||||
|
mCursor += offset;
|
||||||
|
if(mCursor < 0)
|
||||||
|
mCursor += mEntries.size();
|
||||||
|
if(mCursor >= (int)mEntries.size())
|
||||||
|
mCursor -= mEntries.size();
|
||||||
|
|
||||||
|
onCursorChanged(CURSOR_SCROLLING);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void ImageGridComponent<T>::setScrollDir(Eigen::Vector2i dir)
|
||||||
|
{
|
||||||
|
mScrollDir = dir;
|
||||||
|
mScrollAccumulator = -SCROLL_DELAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool ImageGridComponent<T>::input(InputConfig* config, Input input)
|
||||||
|
{
|
||||||
|
if(input.value != 0)
|
||||||
|
{
|
||||||
|
Eigen::Vector2i dir = Eigen::Vector2i::Zero();
|
||||||
|
if(config->isMappedTo("up", input))
|
||||||
|
dir[1] = -1;
|
||||||
|
else if(config->isMappedTo("down", input))
|
||||||
|
dir[1] = 1;
|
||||||
|
else if(config->isMappedTo("left", input))
|
||||||
|
dir[0] = -1;
|
||||||
|
else if(config->isMappedTo("right", input))
|
||||||
|
dir[0] = 1;
|
||||||
|
|
||||||
|
if(dir != Eigen::Vector2i::Zero())
|
||||||
|
{
|
||||||
|
setScrollDir(dir);
|
||||||
|
scroll();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if(config->isMappedTo("up", input) || config->isMappedTo("down", input) || config->isMappedTo("left", input) || config->isMappedTo("right", input))
|
||||||
|
{
|
||||||
|
mScrollDir << 0, 0;
|
||||||
|
onCursorChanged(CURSOR_STOPPED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return GuiComponent::input(config, input);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void ImageGridComponent<T>::update(int deltaTime)
|
||||||
|
{
|
||||||
|
if(mScrollDir != Eigen::Vector2i::Zero())
|
||||||
|
{
|
||||||
|
mScrollAccumulator += deltaTime;
|
||||||
|
while(mScrollAccumulator >= SCROLL_TIME)
|
||||||
|
{
|
||||||
|
scroll();
|
||||||
|
mScrollAccumulator -= SCROLL_TIME;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void ImageGridComponent<T>::render(const Eigen::Affine3f& parentTrans)
|
||||||
|
{
|
||||||
|
Eigen::Affine3f trans = getTransform() * parentTrans;
|
||||||
|
|
||||||
|
if(mEntriesDirty)
|
||||||
|
{
|
||||||
|
buildImages();
|
||||||
|
updateImages();
|
||||||
|
mEntriesDirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto it = mImages.begin(); it != mImages.end(); it++)
|
||||||
|
{
|
||||||
|
it->render(trans);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderChildren(trans);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void ImageGridComponent<T>::onCursorChanged(CursorState state)
|
||||||
|
{
|
||||||
|
updateImages();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void ImageGridComponent<T>::onSizeChanged()
|
||||||
|
{
|
||||||
|
buildImages();
|
||||||
|
updateImages();
|
||||||
|
}
|
||||||
|
|
||||||
|
// create and position imagecomponents (mImages)
|
||||||
|
template<typename T>
|
||||||
|
void ImageGridComponent<T>::buildImages()
|
||||||
|
{
|
||||||
|
mImages.clear();
|
||||||
|
|
||||||
|
Eigen::Vector2i gridSize = getGridSize();
|
||||||
|
Eigen::Vector2f squareSize = getMaxSquareSize();
|
||||||
|
Eigen::Vector2f padding = getPadding();
|
||||||
|
|
||||||
|
// attempt to center within our size
|
||||||
|
Eigen::Vector2f totalSize(gridSize.x() * (squareSize.x() + padding.x()), gridSize.y() * (squareSize.y() + padding.y()));
|
||||||
|
Eigen::Vector2f offset(mSize.x() - totalSize.x(), mSize.y() - totalSize.y());
|
||||||
|
offset /= 2;
|
||||||
|
|
||||||
|
for(int y = 0; y < gridSize.y(); y++)
|
||||||
|
{
|
||||||
|
for(int x = 0; x < gridSize.x(); x++)
|
||||||
|
{
|
||||||
|
mImages.push_back(ImageComponent(mWindow));
|
||||||
|
ImageComponent& image = mImages.at(y * gridSize.x() + x);
|
||||||
|
|
||||||
|
image.setPosition((squareSize.x() + padding.x()) * (x + 0.5f) + offset.x(), (squareSize.y() + padding.y()) * (y + 0.5f) + offset.y());
|
||||||
|
image.setOrigin(0.5f, 0.5f);
|
||||||
|
image.setResize(squareSize.x(), squareSize.y(), true);
|
||||||
|
image.setImage("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void ImageGridComponent<T>::updateImages()
|
||||||
|
{
|
||||||
|
if(mImages.empty())
|
||||||
|
buildImages();
|
||||||
|
|
||||||
|
Eigen::Vector2i gridSize = getGridSize();
|
||||||
|
|
||||||
|
int cursorRow = mCursor / gridSize.x();
|
||||||
|
int cursorCol = mCursor % gridSize.x();
|
||||||
|
|
||||||
|
int start = (cursorRow - (gridSize.y() / 2)) * gridSize.x();
|
||||||
|
|
||||||
|
//if we're at the end put the row as close as we can and no higher
|
||||||
|
if(start + (gridSize.x() * gridSize.y()) >= (int)mEntries.size())
|
||||||
|
start = gridSize.x() * ((int)mEntries.size()/gridSize.x() - gridSize.y() + 1);
|
||||||
|
|
||||||
|
if(start < 0)
|
||||||
|
start = 0;
|
||||||
|
|
||||||
|
unsigned int i = (unsigned int)start;
|
||||||
|
for(unsigned int img = 0; img < mImages.size(); img++)
|
||||||
|
{
|
||||||
|
ImageComponent& image = mImages.at(img);
|
||||||
|
if(i >= mEntries.size())
|
||||||
|
{
|
||||||
|
image.setImage("");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Eigen::Vector2f squareSize = getSquareSize(mEntries.at(i).texture);
|
||||||
|
if(i == mCursor)
|
||||||
|
{
|
||||||
|
image.setColorShift(0xFFFFFFFF);
|
||||||
|
image.setResize(squareSize.x() + getPadding().x() * 0.95f, squareSize.y() + getPadding().y() * 0.95f, true);
|
||||||
|
}else{
|
||||||
|
image.setColorShift(0xAAAAAABB);
|
||||||
|
image.setResize(squareSize.x(), squareSize.y(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
image.setImage(mEntries.at(i).texture);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
90
src/views/GridGameListView.cpp
Normal file
90
src/views/GridGameListView.cpp
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
#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(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);
|
||||||
|
}
|
||||||
|
}
|
28
src/views/GridGameListView.h
Normal file
28
src/views/GridGameListView.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#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;
|
||||||
|
};
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "BasicGameListView.h"
|
#include "BasicGameListView.h"
|
||||||
#include "DetailedGameListView.h"
|
#include "DetailedGameListView.h"
|
||||||
|
#include "GridGameListView.h"
|
||||||
|
|
||||||
ViewController::ViewController(Window* window)
|
ViewController::ViewController(Window* window)
|
||||||
: GuiComponent(window), mCurrentView(nullptr), mCameraPos(Eigen::Affine3f::Identity())
|
: GuiComponent(window), mCurrentView(nullptr), mCameraPos(Eigen::Affine3f::Identity())
|
||||||
|
@ -119,6 +120,9 @@ std::shared_ptr<GameListView> ViewController::getSystemView(SystemData* system)
|
||||||
else
|
else
|
||||||
view = std::shared_ptr<GameListView>(new BasicGameListView(mWindow, system->getRootFolder()));
|
view = std::shared_ptr<GameListView>(new BasicGameListView(mWindow, system->getRootFolder()));
|
||||||
|
|
||||||
|
|
||||||
|
//view = std::shared_ptr<GameListView>(new GridGameListView(mWindow, system->getRootFolder()));
|
||||||
|
|
||||||
view->setTheme(system->getTheme());
|
view->setTheme(system->getTheme());
|
||||||
}else{
|
}else{
|
||||||
LOG(LogError) << "null system"; // should eventually return an "all games" gamelist view
|
LOG(LogError) << "null system"; // should eventually return an "all games" gamelist view
|
||||||
|
|
Loading…
Reference in a new issue