Added support to the new gamelist classes for changing view styles.

Also removed the deprecated 'grid' view style and corresponding menu option.
This commit is contained in:
Leon Styhre 2022-01-18 22:04:05 +01:00
parent 4e444c369c
commit 21b167ed9b
7 changed files with 127 additions and 47 deletions

View file

@ -136,7 +136,6 @@ void GuiMenu::openUIOptions()
gamelist_view_style->add("basic", "basic", selectedViewStyle == "basic"); gamelist_view_style->add("basic", "basic", selectedViewStyle == "basic");
gamelist_view_style->add("detailed", "detailed", selectedViewStyle == "detailed"); gamelist_view_style->add("detailed", "detailed", selectedViewStyle == "detailed");
gamelist_view_style->add("video", "video", selectedViewStyle == "video"); gamelist_view_style->add("video", "video", selectedViewStyle == "video");
gamelist_view_style->add("grid (deprecated)", "grid", selectedViewStyle == "grid");
// If there are no objects returned, then there must be a manually modified entry in the // If there are no objects returned, then there must be a manually modified entry in the
// configuration file. Simply set the view style to Automatic in this case. // configuration file. Simply set the view style to Automatic in this case.
if (gamelist_view_style->getSelectedObjects().size() == 0) if (gamelist_view_style->getSelectedObjects().size() == 0)

View file

@ -19,7 +19,14 @@ GamelistBase::GamelistBase(Window* window, FileData* root)
, mRoot {root} , mRoot {root}
, mList {window} , mList {window}
, mRandomGame {nullptr} , mRandomGame {nullptr}
, mLastUpdated(nullptr) , mLastUpdated {nullptr}
, mGameCount {0}
, mFavoritesGameCount {0}
, mFilteredGameCount {0}
, mFilteredGameCountAll {0}
, mIsFiltered {false}
, mIsFolder {false}
, mVideoPlaying {false}
{ {
setSize(static_cast<float>(Renderer::getScreenWidth()), setSize(static_cast<float>(Renderer::getScreenWidth()),
static_cast<float>(Renderer::getScreenHeight())); static_cast<float>(Renderer::getScreenHeight()));

View file

@ -20,6 +20,7 @@
#include "components/ScrollableContainer.h" #include "components/ScrollableContainer.h"
#include "components/TextComponent.h" #include "components/TextComponent.h"
#include "components/TextListComponent.h" #include "components/TextListComponent.h"
#include "components/VideoFFmpegComponent.h"
#include <stack> #include <stack>
@ -96,6 +97,7 @@ protected:
unsigned int mFilteredGameCountAll; unsigned int mFilteredGameCountAll;
bool mIsFiltered; bool mIsFiltered;
bool mIsFolder; bool mIsFolder;
bool mVideoPlaying;
private: private:
}; };

View file

@ -17,12 +17,14 @@
GamelistView::GamelistView(Window* window, FileData* root) GamelistView::GamelistView(Window* window, FileData* root)
: GamelistBase {window, root} : GamelistBase {window, root}
, mViewStyle {ViewController::BASIC}
, mHeaderText {window} , mHeaderText {window}
, mHeaderImage {window} , mHeaderImage {window}
, mBackground {window} , mBackground {window}
, mThumbnail {window} , mThumbnail {window}
, mMarquee {window} , mMarquee {window}
, mImage {window} , mImage {window}
, mVideo(nullptr)
, mLblRating {window} , mLblRating {window}
, mLblReleaseDate {window} , mLblReleaseDate {window}
, mLblDeveloper {window} , mLblDeveloper {window}
@ -45,6 +47,8 @@ GamelistView::GamelistView(Window* window, FileData* root)
, mDescription {window} , mDescription {window}
, mGamelistInfo {window} , mGamelistInfo {window}
{ {
mViewStyle = ViewController::getInstance()->getState().viewstyle;
mHeaderText.setText("Logo Text", false); mHeaderText.setText("Logo Text", false);
mHeaderText.setSize(mSize.x, 0.0f); mHeaderText.setSize(mSize.x, 0.0f);
mHeaderText.setPosition(0.0f, 0.0f); mHeaderText.setPosition(0.0f, 0.0f);
@ -66,6 +70,11 @@ GamelistView::GamelistView(Window* window, FileData* root)
const float padding = 0.01f; const float padding = 0.01f;
if (mViewStyle == ViewController::VIDEO) {
// Create the video window.
mVideo = new VideoFFmpegComponent(window);
}
mList.setPosition(mSize.x * (0.50f + padding), mList.getPosition().y); mList.setPosition(mSize.x * (0.50f + padding), mList.getPosition().y);
mList.setSize(mSize.x * (0.50f - padding), mList.getSize().y); mList.setSize(mSize.x * (0.50f - padding), mList.getSize().y);
mList.setAlignment(TextListComponent<FileData*>::ALIGN_LEFT); mList.setAlignment(TextListComponent<FileData*>::ALIGN_LEFT);
@ -95,6 +104,15 @@ GamelistView::GamelistView(Window* window, FileData* root)
mImage.setDefaultZIndex(30.0f); mImage.setDefaultZIndex(30.0f);
addChild(&mImage); addChild(&mImage);
if (mViewStyle == ViewController::VIDEO) {
// Video.
mVideo->setOrigin(0.5f, 0.5f);
mVideo->setPosition(mSize.x * 0.25f, mSize.y * 0.4f);
mVideo->setSize(mSize.x * (0.5f - 2.0f * padding), mSize.y * 0.4f);
mVideo->setDefaultZIndex(30.0f);
addChild(mVideo);
}
// Metadata labels + values. // Metadata labels + values.
mLblRating.setText("Rating: ", false); mLblRating.setText("Rating: ", false);
addChild(&mLblRating); addChild(&mLblRating);
@ -165,6 +183,9 @@ GamelistView::~GamelistView()
delete extra; delete extra;
} }
mThemeExtras.clear(); mThemeExtras.clear();
if (mViewStyle == ViewController::VIDEO && mVideo != nullptr)
delete mVideo;
} }
void GamelistView::onFileChanged(FileData* file, bool reloadGamelist) void GamelistView::onFileChanged(FileData* file, bool reloadGamelist)
@ -235,6 +256,12 @@ void GamelistView::onThemeChanged(const std::shared_ptr<ThemeData>& theme)
POSITION | ThemeFlags::SIZE | Z_INDEX | ROTATION | VISIBLE); POSITION | ThemeFlags::SIZE | Z_INDEX | ROTATION | VISIBLE);
mImage.applyTheme(theme, getName(), "md_image", mImage.applyTheme(theme, getName(), "md_image",
POSITION | ThemeFlags::SIZE | Z_INDEX | ROTATION | VISIBLE); POSITION | ThemeFlags::SIZE | Z_INDEX | ROTATION | VISIBLE);
if (mViewStyle == ViewController::VIDEO) {
mVideo->applyTheme(theme, getName(), "md_video",
POSITION | ThemeFlags::SIZE | ThemeFlags::DELAY | Z_INDEX | ROTATION |
VISIBLE);
}
mName.applyTheme(theme, getName(), "md_name", ALL); mName.applyTheme(theme, getName(), "md_name", ALL);
mBadges.applyTheme(theme, getName(), "md_badges", ALL); mBadges.applyTheme(theme, getName(), "md_badges", ALL);
@ -277,12 +304,23 @@ void GamelistView::onThemeChanged(const std::shared_ptr<ThemeData>& theme)
void GamelistView::update(int deltaTime) void GamelistView::update(int deltaTime)
{ {
// TEMPORARY
// BasicGamelistView::update(deltaTime);
mImage.update(deltaTime); mImage.update(deltaTime);
if (ViewController::getInstance()->getGameLaunchTriggered() && mImage.isAnimationPlaying(0)) if (ViewController::getInstance()->getGameLaunchTriggered() && mImage.isAnimationPlaying(0))
mImage.finishAnimation(0); mImage.finishAnimation(0);
if (mViewStyle == ViewController::VIDEO) {
if (!mVideoPlaying)
mVideo->onHide();
else if (mVideoPlaying && !mVideo->isVideoPaused() && !mWindow->isScreensaverActive())
mVideo->onShow();
mVideo->update(deltaTime);
if (ViewController::getInstance()->getGameLaunchTriggered() &&
mVideo->isAnimationPlaying(0))
mVideo->finishAnimation(0);
}
} }
void GamelistView::render(const glm::mat4& parentTrans) void GamelistView::render(const glm::mat4& parentTrans)
@ -392,7 +430,7 @@ void GamelistView::updateInfoPanel()
mLastUpdated->getPath() == mLastUpdated->getSystem()->getName())) mLastUpdated->getPath() == mLastUpdated->getSystem()->getName()))
hideMetaDataFields = true; hideMetaDataFields = true;
if (hideMetaDataFields) { if (hideMetaDataFields || mViewStyle == ViewController::BASIC) {
mLblRating.setVisible(false); mLblRating.setVisible(false);
mRating.setVisible(false); mRating.setVisible(false);
mLblReleaseDate.setVisible(false); mLblReleaseDate.setVisible(false);
@ -433,6 +471,7 @@ void GamelistView::updateInfoPanel()
bool fadingOut = false; bool fadingOut = false;
if (file == nullptr) { if (file == nullptr) {
mVideoPlaying = false;
fadingOut = true; fadingOut = true;
} }
else { else {
@ -447,19 +486,45 @@ void GamelistView::updateInfoPanel()
mThumbnail.setImage(mRandomGame->getThumbnailPath()); mThumbnail.setImage(mRandomGame->getThumbnailPath());
mMarquee.setImage(mRandomGame->getMarqueePath(), false, true); mMarquee.setImage(mRandomGame->getMarqueePath(), false, true);
mImage.setImage(mRandomGame->getImagePath()); mImage.setImage(mRandomGame->getImagePath());
if (mViewStyle == ViewController::VIDEO) {
mVideo->setImage(mRandomGame->getImagePath());
// Always stop the video before setting a new video as it will otherwise
// continue to play if it has the same path (i.e. it is the same physical video
// file) as the previously set video. That may happen when entering a folder
// with the same name as the first game file inside, or as in this case, when
// entering a custom collection.
mVideo->onHide();
if (!mVideo->setVideo(mRandomGame->getVideoPath()))
mVideo->setDefaultVideo();
}
} }
else { else {
mThumbnail.setImage(""); mThumbnail.setImage("");
mMarquee.setImage(""); mMarquee.setImage("");
mImage.setImage(""); mImage.setImage("");
if (mViewStyle == ViewController::VIDEO) {
mVideo->setImage("");
mVideo->setVideo("");
mVideo->setDefaultVideo();
}
} }
} }
else { else {
mThumbnail.setImage(file->getThumbnailPath()); mThumbnail.setImage(file->getThumbnailPath());
mMarquee.setImage(file->getMarqueePath(), false, true); mMarquee.setImage(file->getMarqueePath(), false, true);
mImage.setImage(file->getImagePath()); mImage.setImage(file->getImagePath());
if (mViewStyle == ViewController::VIDEO) {
mVideo->setImage(file->getImagePath());
mVideo->onHide();
if (!mVideo->setVideo(file->getVideoPath()))
mVideo->setDefaultVideo();
}
} }
mVideoPlaying = true;
// Populate the gamelistInfo field which shows an icon if a folder has been entered // Populate the gamelistInfo field which shows an icon if a folder has been entered
// as well as the game count for the entire system (total and favorites separately). // as well as the game count for the entire system (total and favorites separately).
// If a filter has been applied, then the number of filtered and total games replaces // If a filter has been applied, then the number of filtered and total games replaces
@ -495,12 +560,22 @@ void GamelistView::updateInfoPanel()
mGamelistInfo.setValue(gamelistInfoString); mGamelistInfo.setValue(gamelistInfoString);
// Fade in the game image. if (mViewStyle == ViewController::DETAILED) {
auto func = [this](float t) { // Fade in the game image.
mImage.setOpacity(static_cast<unsigned char>( auto func = [this](float t) {
glm::mix(static_cast<float>(FADE_IN_START_OPACITY), 1.0f, t) * 255)); mImage.setOpacity(static_cast<unsigned char>(
}; glm::mix(static_cast<float>(FADE_IN_START_OPACITY), 1.0f, t) * 255));
mImage.setAnimation(new LambdaAnimation(func, FADE_IN_TIME), 0, nullptr, false); };
mImage.setAnimation(new LambdaAnimation(func, FADE_IN_TIME), 0, nullptr, false);
}
else if (mViewStyle == ViewController::VIDEO) {
// Fade in the static image.
auto func = [this](float t) {
mVideo->setOpacity(static_cast<unsigned char>(
glm::mix(static_cast<float>(FADE_IN_START_OPACITY), 1.0f, t) * 255));
};
mVideo->setAnimation(new LambdaAnimation(func, FADE_IN_TIME), 0, nullptr, false);
}
mDescription.setText(file->metadata.get("desc")); mDescription.setText(file->metadata.get("desc"));
mDescContainer.reset(); mDescContainer.reset();

View file

@ -27,7 +27,20 @@ public:
void preloadGamelist() { updateInfoPanel(); } void preloadGamelist() { updateInfoPanel(); }
void launch(FileData* game) override { ViewController::getInstance()->triggerGameLaunch(game); } void launch(FileData* game) override { ViewController::getInstance()->triggerGameLaunch(game); }
std::string getName() const { return "detailed"; } std::string getName() const
{
auto selectedViewStyle = ViewController::getInstance()->getState();
switch (selectedViewStyle.viewstyle) {
case ViewController::VIDEO:
return "video";
case ViewController::DETAILED:
return "detailed";
case ViewController::BASIC:
return "basic";
default:
return "basic";
}
}
const std::shared_ptr<ThemeData> getTheme() const { return mTheme; } const std::shared_ptr<ThemeData> getTheme() const { return mTheme; }
void setTheme(const std::shared_ptr<ThemeData>& theme) void setTheme(const std::shared_ptr<ThemeData>& theme)
@ -49,6 +62,8 @@ private:
void initMDLabels(); void initMDLabels();
void initMDValues(); void initMDValues();
ViewController::GamelistViewStyle mViewStyle;
std::vector<TextComponent*> getMDLabels(); std::vector<TextComponent*> getMDLabels();
std::vector<GuiComponent*> getMDValues(); std::vector<GuiComponent*> getMDValues();
@ -62,6 +77,7 @@ private:
ImageComponent mThumbnail; ImageComponent mThumbnail;
ImageComponent mMarquee; ImageComponent mMarquee;
ImageComponent mImage; ImageComponent mImage;
VideoComponent* mVideo;
TextComponent mLblRating; TextComponent mLblRating;
TextComponent mLblReleaseDate; TextComponent mLblReleaseDate;

View file

@ -545,8 +545,6 @@ void ViewController::goToGamelist(SystemData* system)
mState.viewstyle = DETAILED; mState.viewstyle = DETAILED;
else if (viewStyle == "video") else if (viewStyle == "video")
mState.viewstyle = VIDEO; mState.viewstyle = VIDEO;
else if (viewStyle == "grid")
mState.viewstyle = GRID;
} }
if (mCurrentView) if (mCurrentView)
@ -736,8 +734,6 @@ std::shared_ptr<GamelistView> ViewController::getGamelistView(SystemData* system
selectedViewStyle = BASIC; selectedViewStyle = BASIC;
if (viewPreference.compare("detailed") == 0) if (viewPreference.compare("detailed") == 0)
selectedViewStyle = DETAILED; selectedViewStyle = DETAILED;
if (viewPreference.compare("grid") == 0)
selectedViewStyle = GRID;
if (viewPreference.compare("video") == 0) if (viewPreference.compare("video") == 0)
selectedViewStyle = VIDEO; selectedViewStyle = VIDEO;
@ -756,38 +752,24 @@ std::shared_ptr<GamelistView> ViewController::getGamelistView(SystemData* system
} }
// Create the view. // Create the view.
/* switch (selectedViewStyle) {
switch (selectedViewStyle) { case VIDEO: {
case VIDEO: { mState.viewstyle = VIDEO;
view = std::shared_ptr<IGamelistView>( break;
new VideoGamelistView(mWindow, system->getRootFolder()));
mState.viewstyle = VIDEO;
break;
}
case DETAILED: {
view = std::shared_ptr<IGamelistView>(
new DetailedGamelistView(mWindow, system->getRootFolder()));
mState.viewstyle = DETAILED;
break;
}
case GRID: {
view = std::shared_ptr<IGamelistView>(
new GridGamelistView(mWindow, system->getRootFolder()));
mState.viewstyle = GRID;
break;
}
case BASIC: {
}
default: {
view = std::shared_ptr<IGamelistView>(
new BasicGamelistView(mWindow, system->getRootFolder()));
mState.viewstyle = BASIC;
break;
}
} }
*/ case DETAILED: {
mState.viewstyle = DETAILED;
break;
}
case BASIC: {
}
default: {
mState.viewstyle = BASIC;
break;
}
}
view = std::shared_ptr<GamelistView>(new GamelistView(mWindow, system->getRootFolder())); view = std::shared_ptr<GamelistView>(new GamelistView(mWindow, system->getRootFolder()));
mState.viewstyle = DETAILED;
view->setTheme(system->getTheme()); view->setTheme(system->getTheme());

View file

@ -89,7 +89,6 @@ public:
AUTOMATIC, // Replace with AllowShortEnumsOnASingleLine: false (clang-format >=11.0). AUTOMATIC, // Replace with AllowShortEnumsOnASingleLine: false (clang-format >=11.0).
BASIC, BASIC,
DETAILED, DETAILED,
GRID,
VIDEO VIDEO
}; };