Added support for defining multiple imageType entries.

Also made some improvements to GameSelectorComponent and related logic.
This commit is contained in:
Leon Styhre 2022-02-14 19:32:07 +01:00
parent eb3729a5fb
commit 4f019c3775
17 changed files with 369 additions and 154 deletions

View file

@ -765,6 +765,9 @@ void FileData::countGames(std::pair<unsigned int, unsigned int>& gameCount)
void FileData::updateLastPlayedList()
{
if (mUpdateListCallback)
mUpdateListCallback();
if (!mUpdateChildrenLastPlayed)
return;
@ -780,6 +783,9 @@ void FileData::updateLastPlayedList()
void FileData::updateMostPlayedList()
{
if (mUpdateListCallback)
mUpdateListCallback();
if (!mUpdateChildrenMostPlayed)
return;

View file

@ -14,6 +14,7 @@
#include "MetaData.h"
#include "utils/FileSystemUtil.h"
#include <functional>
#include <unordered_map>
class SystemData;
@ -62,6 +63,7 @@ public:
const std::vector<FileData*>& getChildrenMostPlayed() const { return mChildrenMostPlayed; }
void setUpdateChildrenLastPlayed(bool state) { mUpdateChildrenLastPlayed = state; }
void setUpdateChildrenMostPlayed(bool state) { mUpdateChildrenMostPlayed = state; }
void setUpdateListCallback(const std::function<void()>& func) { mUpdateListCallback = func; }
const bool getOnlyFoldersFlag() const { return mOnlyFolders; }
const bool getHasFoldersFlag() const { return mHasFolders; }
@ -156,6 +158,7 @@ private:
std::vector<FileData*> mFilteredChildren;
std::vector<FileData*> mChildrenLastPlayed;
std::vector<FileData*> mChildrenMostPlayed;
std::function<void()> mUpdateListCallback;
// The pair includes all games, and favorite games.
std::pair<unsigned int, unsigned int> mGameCount;
bool mOnlyFolders;

View file

@ -107,7 +107,7 @@ void GamelistView::onThemeChanged(const std::shared_ptr<ThemeData>& theme)
mImageComponents.push_back(std::make_unique<ImageComponent>());
mImageComponents.back()->setDefaultZIndex(30.0f);
mImageComponents.back()->applyTheme(theme, "gamelist", element.first, ALL);
if (mImageComponents.back()->getThemeImageType() != "")
if (mImageComponents.back()->getThemeImageTypes().size() != 0)
mImageComponents.back()->setScrollHide(true);
addChild(mImageComponents.back().get());
}
@ -116,7 +116,7 @@ void GamelistView::onThemeChanged(const std::shared_ptr<ThemeData>& theme)
mVideoComponents.back()->setDefaultZIndex(30.0f);
addChild(mVideoComponents.back().get());
mVideoComponents.back()->applyTheme(theme, "gamelist", element.first, ALL);
if (mVideoComponents.back()->getThemeImageType() != "")
if (mVideoComponents.back()->getThemeImageTypes().size() != 0)
mVideoComponents.back()->setScrollHide(true);
}
else if (element.second.type == "animation") {
@ -387,50 +387,11 @@ void GamelistView::updateInfoPanel()
mRandomGame = CollectionSystemsManager::getInstance()->updateCollectionFolderMetadata(
file->getSystem());
if (mRandomGame) {
for (auto& image : mImageComponents) {
if (image->getThemeImageType() == "image")
image->setImage(mRandomGame->getImagePath());
else if (image->getThemeImageType() == "miximage")
image->setImage(mRandomGame->getMiximagePath());
else if (image->getThemeImageType() == "marquee")
image->setImage(mRandomGame->getMarqueePath());
else if (image->getThemeImageType() == "screenshot")
image->setImage(mRandomGame->getScreenshotPath());
else if (image->getThemeImageType() == "titlescreen")
image->setImage(mRandomGame->getTitleScreenPath());
else if (image->getThemeImageType() == "cover")
image->setImage(mRandomGame->getCoverPath());
else if (image->getThemeImageType() == "backcover")
image->setImage(mRandomGame->getBackCoverPath());
else if (image->getThemeImageType() == "3dbox")
image->setImage(mRandomGame->get3DBoxPath());
else if (image->getThemeImageType() == "fanart")
image->setImage(mRandomGame->getFanArtPath());
else if (image->getThemeImageType() == "thumbnail")
image->setImage(mRandomGame->getThumbnailPath());
}
for (auto& image : mImageComponents)
setGameImage(mRandomGame, image.get());
for (auto& video : mVideoComponents) {
if (video->getThemeImageType() == "image")
video->setImage(mRandomGame->getImagePath());
else if (video->getThemeImageType() == "miximage")
video->setImage(mRandomGame->getMiximagePath());
else if (video->getThemeImageType() == "marquee")
video->setImage(mRandomGame->getMarqueePath());
else if (video->getThemeImageType() == "screenshot")
video->setImage(mRandomGame->getScreenshotPath());
else if (video->getThemeImageType() == "titlescreen")
video->setImage(mRandomGame->getTitleScreenPath());
else if (video->getThemeImageType() == "cover")
video->setImage(mRandomGame->getCoverPath());
else if (video->getThemeImageType() == "backcover")
video->setImage(mRandomGame->getBackCoverPath());
else if (video->getThemeImageType() == "3dbox")
video->setImage(mRandomGame->get3DBoxPath());
else if (video->getThemeImageType() == "fanart")
video->setImage(mRandomGame->getFanArtPath());
else if (video->getThemeImageType() == "thumbnail")
video->setImage(mRandomGame->getThumbnailPath());
setGameImage(mRandomGame, video.get());
// 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
@ -447,7 +408,7 @@ void GamelistView::updateInfoPanel()
}
else {
for (auto& image : mImageComponents) {
if (image->getThemeImageType() != "")
if (image->getThemeImageTypes().size() != 0)
image->setImage("");
}
@ -465,51 +426,11 @@ void GamelistView::updateInfoPanel()
}
}
else {
for (auto& image : mImageComponents) {
if (image->getThemeImageType() == "image")
image->setImage(file->getImagePath());
else if (image->getThemeImageType() == "miximage")
image->setImage(file->getMiximagePath());
else if (image->getThemeImageType() == "marquee")
image->setImage(file->getMarqueePath());
else if (image->getThemeImageType() == "screenshot")
image->setImage(file->getScreenshotPath());
else if (image->getThemeImageType() == "titlescreen")
image->setImage(file->getTitleScreenPath());
else if (image->getThemeImageType() == "cover")
image->setImage(file->getCoverPath());
else if (image->getThemeImageType() == "backcover")
image->setImage(file->getBackCoverPath());
else if (image->getThemeImageType() == "3dbox")
image->setImage(file->get3DBoxPath());
else if (image->getThemeImageType() == "fanart")
image->setImage(file->getFanArtPath());
else if (image->getThemeImageType() == "thumbnail")
image->setImage(file->getThumbnailPath());
}
for (auto& image : mImageComponents)
setGameImage(file, image.get());
for (auto& video : mVideoComponents) {
if (video->getThemeImageType() == "image")
video->setImage(file->getImagePath());
else if (video->getThemeImageType() == "miximage")
video->setImage(file->getMiximagePath());
else if (video->getThemeImageType() == "marquee")
video->setImage(file->getMarqueePath());
else if (video->getThemeImageType() == "screenshot")
video->setImage(file->getScreenshotPath());
else if (video->getThemeImageType() == "titlescreen")
video->setImage(file->getTitleScreenPath());
else if (video->getThemeImageType() == "cover")
video->setImage(file->getCoverPath());
else if (video->getThemeImageType() == "backcover")
video->setImage(file->getBackCoverPath());
else if (video->getThemeImageType() == "3dbox")
video->setImage(file->get3DBoxPath());
else if (video->getThemeImageType() == "fanart")
video->setImage(file->getFanArtPath());
else if (video->getThemeImageType() == "thumbnail")
video->setImage(file->getThumbnailPath());
setGameImage(file, video.get());
video->onHide();
if (video->hasStaticVideo())
@ -767,3 +688,83 @@ void GamelistView::updateInfoPanel()
}
}
}
void GamelistView::setGameImage(FileData* file, GuiComponent* comp)
{
std::string path;
for (auto& imageType : comp->getThemeImageTypes()) {
if (imageType == "image") {
path = file->getImagePath();
if (path != "") {
comp->setImage(path);
break;
}
}
else if (imageType == "miximage") {
path = file->getMiximagePath();
if (path != "") {
comp->setImage(path);
break;
}
}
else if (imageType == "marquee") {
path = file->getMarqueePath();
if (path != "") {
comp->setImage(path);
break;
}
}
else if (imageType == "screenshot") {
path = file->getScreenshotPath();
if (path != "") {
comp->setImage(path);
break;
}
}
else if (imageType == "titlescreen") {
path = file->getTitleScreenPath();
if (path != "") {
comp->setImage(path);
break;
}
}
else if (imageType == "cover") {
path = file->getCoverPath();
if (path != "") {
comp->setImage(path);
break;
}
}
else if (imageType == "backcover") {
path = file->getBackCoverPath();
if (path != "") {
comp->setImage(path);
break;
}
}
else if (imageType == "3dbox") {
path = file->get3DBoxPath();
if (path != "") {
comp->setImage(path);
break;
}
}
else if (imageType == "fanart") {
path = file->getFanArtPath();
if (path != "") {
comp->setImage(path);
break;
}
}
else if (imageType == "thumbnail") {
path = file->getThumbnailPath();
if (path != "") {
comp->setImage(path);
break;
}
}
}
// This is needed so the default image is set if no game media was found.
if (path == "" && comp->getThemeImageTypes().size() > 0)
comp->setImage("");
}

View file

@ -57,6 +57,7 @@ public:
private:
void updateInfoPanel();
void setGameImage(FileData* file, GuiComponent* comp);
// Legacy (backward compatibility) functions.
void legacyPopulateFields();

View file

@ -62,8 +62,14 @@ SystemView::~SystemView()
void SystemView::goToSystem(SystemData* system, bool animate)
{
mCarousel->setCursor(system);
for (auto& selector : mSystemElements[mCarousel->getCursor()].gameSelectors) {
if (selector->getGameSelection() == GameSelectorComponent::GameSelection::RANDOM)
selector->setNeedsRefresh();
}
updateGameSelectors();
updateGameCount();
updateGameSelector();
if (!animate)
finishSystemAnimation(0);
@ -174,13 +180,20 @@ HelpStyle SystemView::getHelpStyle()
void SystemView::onCursorChanged(const CursorState& /*state*/)
{
int cursor {mCarousel->getCursor()};
for (auto& selector : mSystemElements[cursor].gameSelectors) {
if (selector->getGameSelection() == GameSelectorComponent::GameSelection::RANDOM)
selector->setNeedsRefresh();
}
updateGameSelectors();
updateHelpPrompts();
updateGameSelector();
int scrollVelocity {mCarousel->getScrollingVelocity()};
float startPos {mCamOffset};
float posMax {static_cast<float>(mCarousel->getNumEntries())};
float target {static_cast<float>(mCarousel->getCursor())};
float target {static_cast<float>(cursor)};
// Find the shortest path to the target.
float endPos {target}; // Directly.
@ -337,10 +350,11 @@ void SystemView::populate()
elements.fullName = it->getFullName();
for (auto& element : theme->getViewElements("system").elements) {
if (element.second.type == "gameselector") {
elements.gameSelector = std::make_unique<GameSelectorComponent>(it);
elements.gameSelector->applyTheme(theme, "system", element.first,
ThemeFlags::ALL);
elements.gameSelector->refreshGames();
elements.gameSelectors.emplace_back(
std::make_unique<GameSelectorComponent>(it));
elements.gameSelectors.back()->applyTheme(theme, "system", element.first,
ThemeFlags::ALL);
elements.gameSelectors.back()->setNeedsRefresh();
}
if (element.second.type == "carousel") {
mCarousel->applyTheme(theme, "system", element.first, ThemeFlags::ALL);
@ -354,7 +368,7 @@ void SystemView::populate()
elements.imageComponents.back()->setDefaultZIndex(30.0f);
elements.imageComponents.back()->applyTheme(theme, "system", element.first,
ThemeFlags::ALL);
if (elements.imageComponents.back()->getThemeImageType() != "")
if (elements.imageComponents.back()->getThemeImageTypes().size() != 0)
elements.imageComponents.back()->setScrollHide(true);
elements.children.emplace_back(elements.imageComponents.back().get());
}
@ -426,7 +440,7 @@ void SystemView::populate()
}
}
updateGameSelector();
updateGameSelectors();
if (mCarousel->getNumEntries() == 0) {
// Something is wrong, there is not a single system to show, check if UI mode is not full.
@ -497,39 +511,182 @@ void SystemView::updateGameCount()
}
}
void SystemView::updateGameSelector()
void SystemView::updateGameSelectors()
{
if (mLegacyMode)
return;
int cursor {mCarousel->getCursor()};
if (mSystemElements[cursor].gameSelector != nullptr) {
mSystemElements[mCarousel->getCursor()].gameSelector->refreshGames();
std::vector<FileData*> games {mSystemElements[cursor].gameSelector->getGames()};
if (mSystemElements[cursor].gameSelectors.size() == 0)
return;
bool multipleSelectors {mSystemElements[cursor].gameSelectors.size() > 1};
for (auto& image : mSystemElements[cursor].imageComponents) {
if (image->getThemeImageTypes().size() == 0)
continue;
GameSelectorComponent* gameSelector {nullptr};
if (multipleSelectors) {
const std::string& imageSelector {image->getThemeGameSelector()};
if (imageSelector == "") {
gameSelector = mSystemElements[cursor].gameSelectors.front().get();
LOG(LogWarning) << "SystemView::updateGameSelectors(): Multiple gameselector "
"elements defined but image element does not state which one to "
"use, so selecting first entry";
}
else {
for (auto& selector : mSystemElements[cursor].gameSelectors) {
if (selector->getSelectorName() == imageSelector)
gameSelector = selector.get();
}
if (gameSelector == nullptr)
gameSelector = mSystemElements[cursor].gameSelectors.front().get();
}
}
else {
gameSelector = mSystemElements[cursor].gameSelectors.front().get();
}
gameSelector->refreshGames();
std::vector<FileData*> games {gameSelector->getGames()};
if (!games.empty()) {
if (!mLegacyMode) {
for (auto& image : mSystemElements[cursor].imageComponents) {
const std::string imageType {image->getThemeImageType()};
if (imageType == "image")
image->setImage(games.front()->getImagePath());
else if (image->getThemeImageType() == "miximage")
image->setImage(games.front()->getMiximagePath());
else if (image->getThemeImageType() == "marquee")
image->setImage(games.front()->getMarqueePath());
else if (image->getThemeImageType() == "screenshot")
image->setImage(games.front()->getScreenshotPath());
else if (image->getThemeImageType() == "titlescreen")
image->setImage(games.front()->getTitleScreenPath());
else if (image->getThemeImageType() == "cover")
image->setImage(games.front()->getCoverPath());
else if (image->getThemeImageType() == "backcover")
image->setImage(games.front()->getBackCoverPath());
else if (image->getThemeImageType() == "3dbox")
image->setImage(games.front()->get3DBoxPath());
else if (image->getThemeImageType() == "fanart")
image->setImage(games.front()->getFanArtPath());
else if (image->getThemeImageType() == "thumbnail")
image->setImage(games.front()->getThumbnailPath());
std::string path;
for (auto& imageType : image->getThemeImageTypes()) {
if (imageType == "image") {
path = games.front()->getImagePath();
if (path != "") {
image->setImage(path);
break;
}
}
else if (imageType == "miximage") {
path = games.front()->getMiximagePath();
if (path != "") {
image->setImage(path);
break;
}
}
else if (imageType == "marquee") {
path = games.front()->getMarqueePath();
if (path != "") {
image->setImage(path);
break;
}
}
else if (imageType == "screenshot") {
path = games.front()->getScreenshotPath();
if (path != "") {
image->setImage(path);
break;
}
}
else if (imageType == "titlescreen") {
path = games.front()->getTitleScreenPath();
if (path != "") {
image->setImage(path);
break;
}
}
else if (imageType == "cover") {
path = games.front()->getCoverPath();
if (path != "") {
image->setImage(path);
break;
}
}
else if (imageType == "backcover") {
path = games.front()->getBackCoverPath();
if (path != "") {
image->setImage(path);
break;
}
}
else if (imageType == "3dbox") {
path = games.front()->get3DBoxPath();
if (path != "") {
image->setImage(path);
break;
}
}
else if (imageType == "fanart") {
path = games.front()->getFanArtPath();
if (path != "") {
image->setImage(path);
break;
}
}
else if (imageType == "thumbnail") {
path = games.front()->getThumbnailPath();
if (path != "") {
image->setImage(path);
break;
}
}
}
// This is needed so the default image is set if no game media was found.
if (path == "" && image->getThemeImageTypes().size() > 0)
image->setImage("");
}
else {
image->setImage("");
}
}
for (auto& text : mSystemElements[cursor].textComponents) {
if (text->getThemeMetadata() == "")
continue;
GameSelectorComponent* gameSelector {nullptr};
if (multipleSelectors) {
const std::string& textSelector {text->getThemeGameSelector()};
if (textSelector == "") {
gameSelector = mSystemElements[cursor].gameSelectors.front().get();
LOG(LogWarning) << "SystemView::updateGameSelectors(): Multiple gameselector "
"elements defined but text element does not state which one to "
"use, so selecting first entry";
}
else {
for (auto& selector : mSystemElements[cursor].gameSelectors) {
if (selector->getSelectorName() == textSelector)
gameSelector = selector.get();
}
if (gameSelector == nullptr)
gameSelector = mSystemElements[cursor].gameSelectors.front().get();
}
}
else {
gameSelector = mSystemElements[cursor].gameSelectors.front().get();
}
gameSelector->refreshGames();
std::vector<FileData*> games {gameSelector->getGames()};
if (!games.empty()) {
const std::string metadata {text->getThemeMetadata()};
if (metadata == "name")
text->setValue(games.front()->metadata.get("name"));
if (metadata == "description")
text->setValue(games.front()->metadata.get("desc"));
if (metadata == "developer")
text->setValue(games.front()->metadata.get("developer"));
if (metadata == "publisher")
text->setValue(games.front()->metadata.get("publisher"));
if (metadata == "genre")
text->setValue(games.front()->metadata.get("genre"));
if (metadata == "players")
text->setValue(games.front()->metadata.get("players"));
if (metadata == "favorite")
text->setValue(games.front()->metadata.get("favorite") == "true" ? "yes" : "no");
if (metadata == "completed")
text->setValue(games.front()->metadata.get("completed") == "true" ? "yes" : "no");
if (metadata == "kidgame")
text->setValue(games.front()->metadata.get("kidgame") == "true" ? "yes" : "no");
if (metadata == "broken")
text->setValue(games.front()->metadata.get("broken") == "true" ? "yes" : "no");
if (metadata == "playcount")
text->setValue(games.front()->metadata.get("playcount"));
if (metadata == "altemulator")
text->setValue(games.front()->metadata.get("altemulator"));
}
else {
text->setValue("");
}
}
}

View file

@ -28,7 +28,7 @@ class SystemData;
struct SystemViewElements {
std::string name;
std::string fullName;
std::unique_ptr<GameSelectorComponent> gameSelector;
std::vector<std::unique_ptr<GameSelectorComponent>> gameSelectors;
std::vector<GuiComponent*> legacyExtras;
std::vector<GuiComponent*> children;
@ -77,7 +77,7 @@ protected:
private:
void populate();
void updateGameCount();
void updateGameSelector();
void updateGameSelectors();
void legacyApplyTheme(const std::shared_ptr<ThemeData>& theme);
void renderElements(const glm::mat4& parentTrans, bool abovePrimary);

View file

@ -364,6 +364,9 @@ void GuiComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
mThemeOpacity = 0.0f;
else
setVisible(true);
if (properties && elem->has("gameselector"))
mThemeGameSelector = elem->get<std::string>("gameselector");
}
void GuiComponent::updateHelpPrompts()

View file

@ -207,16 +207,18 @@ public:
virtual void setOriginalColor(unsigned int color) { mColorOriginalValue = color; }
virtual void setChangedColor(unsigned int color) { mColorChangedValue = color; }
virtual void setImage(const std::string& path, bool tile = false) {}
// These functions are used to enable and disable options in menus, i.e. switches and similar.
virtual bool getEnabled() { return mEnabled; }
virtual void setEnabled(bool state) { mEnabled = state; }
const std::string getThemeSystemdata() { return mThemeSystemdata; }
const std::string& getThemeSystemdata() { return mThemeSystemdata; }
void setThemeSystemdata(const std::string& text) { mThemeSystemdata = text; }
const std::string getThemeMetadata() { return mThemeMetadata; }
const std::string& getThemeMetadata() { return mThemeMetadata; }
void setThemeMetadata(const std::string& text) { mThemeMetadata = text; }
const std::string getThemeImageType() { return mThemeImageType; }
void setThemeImageType(const std::string& text) { mThemeImageType = text; }
const std::vector<std::string>& getThemeImageTypes() { return mThemeImageTypes; }
const std::string& getThemeGameSelector() { return mThemeGameSelector; }
virtual std::shared_ptr<Font> getFont() const { return nullptr; }
@ -279,9 +281,10 @@ protected:
GuiComponent* mParent;
std::vector<GuiComponent*> mChildren;
std::vector<std::string> mThemeImageTypes;
std::string mThemeSystemdata;
std::string mThemeMetadata;
std::string mThemeImageType;
std::string mThemeGameSelector;
unsigned int mColor;
float mSaturation;

View file

@ -89,6 +89,7 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
{"path", PATH},
{"default", PATH},
{"imageType", STRING},
{"gameselector", STRING},
{"tile", BOOLEAN},
{"interpolation", STRING},
{"color", COLOR},
@ -161,6 +162,7 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
{"text", STRING},
{"systemdata", STRING},
{"metadata", STRING},
{"gameselector", STRING},
{"container", BOOLEAN},
{"containerScrollSpeed", FLOAT},
{"containerStartDelay", FLOAT},
@ -281,7 +283,7 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
{"zIndex", FLOAT}}},
{"gameselector",
{{"selection", STRING},
{"count", UNSIGNED_INTEGER}}},
{"gameCount", UNSIGNED_INTEGER}}},
{"helpsystem",
{{"pos", NORMALIZED_PAIR},
{"origin", NORMALIZED_PAIR},

View file

@ -311,6 +311,7 @@ void CarouselComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
mCarouselColor = 0xFFFFFFD8;
mCarouselColorEnd = 0xFFFFFFD8;
mDefaultZIndex = 50.0f;
mText = "";
if (!elem)
return;

View file

@ -19,15 +19,30 @@ public:
GameSelectorComponent(SystemData* system)
: mSystem {system}
, mGameSelection {GameSelection::RANDOM}
, mNeedsRefresh {false}
, mGameCount {1}
{
mSystem->getRootFolder()->setUpdateListCallback([&]() { mNeedsRefresh = true; });
}
enum class GameSelection {
RANDOM, // Replace with AllowShortEnumsOnASingleLine: false (clang-format >=11.0).
LAST_PLAYED,
MOST_PLAYED
};
const std::vector<FileData*>& getGames() const { return mGames; }
void setNeedsRefresh() { mNeedsRefresh = true; }
const bool getNeedsRefresh() { return mNeedsRefresh; }
const GameSelection getGameSelection() const { return mGameSelection; }
const std::string& getSelectorName() const { return mSelectorName; }
void refreshGames()
{
if (!mNeedsRefresh)
return;
mGames.clear();
mNeedsRefresh = false;
bool isKidMode {(Settings::getInstance()->getString("UIMode") == "kid" ||
Settings::getInstance()->getBool("ForceKid"))};
@ -82,6 +97,10 @@ public:
if (!elem)
return;
// Remove the leading "gameselector_" part of the element string in order to directly
// match with the optional "gameselector" property used in other elements.
mSelectorName = element.substr(13, std::string::npos);
if (elem->has("selection")) {
const std::string selection {elem->get<std::string>("selection")};
if (selection == "random") {
@ -105,21 +124,17 @@ public:
}
}
if (elem->has("count"))
mGameCount = glm::clamp(static_cast<int>(elem->get<unsigned int>("count")), 1, 30);
if (elem->has("gameCount"))
mGameCount = glm::clamp(static_cast<int>(elem->get<unsigned int>("gameCount")), 1, 30);
}
private:
enum class GameSelection {
RANDOM, // Replace with AllowShortEnumsOnASingleLine: false (clang-format >=11.0).
LAST_PLAYED,
MOST_PLAYED
};
SystemData* mSystem;
std::vector<FileData*> mGames;
std::string mSelectorName;
GameSelection mGameSelection;
bool mNeedsRefresh;
int mGameCount;
};

View file

@ -148,7 +148,7 @@ bool GridTileComponent::isSelected() const
return mSelected;
}
void GridTileComponent::setImage(const std::string& path)
void GridTileComponent::setImageOLD(const std::string& path)
{
mImage->setImage(path);
@ -156,7 +156,7 @@ void GridTileComponent::setImage(const std::string& path)
resize();
}
void GridTileComponent::setImage(const std::shared_ptr<TextureResource>& texture)
void GridTileComponent::setImageOLD(const std::shared_ptr<TextureResource>& texture)
{
mImage->setImage(texture);

View file

@ -39,10 +39,10 @@ public:
glm::vec2 getSelectedTileSize() const;
bool isSelected() const;
void reset() { setImage(""); }
void reset() { setImageOLD(""); }
void setImage(const std::string& path);
void setImage(const std::shared_ptr<TextureResource>& texture);
void setImageOLD(const std::string& path);
void setImageOLD(const std::shared_ptr<TextureResource>& texture);
void setSelected(bool selected,
bool allowAnimation = true,
glm::vec3* pPosition = nullptr,

View file

@ -14,6 +14,7 @@
#include "Window.h"
#include "resources/TextureResource.h"
#include "utils/CImgUtil.h"
#include "utils/StringUtil.h"
glm::ivec2 ImageComponent::getTextureSize() const
{
@ -522,8 +523,15 @@ void ImageComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
setImage(elem->get<std::string>("path"), tile);
}
if (properties & METADATA && elem->has("imageType"))
mThemeImageType = elem->get<std::string>("imageType");
if (properties && elem->has("imageType")) {
std::string imageTypes {elem->get<std::string>("imageType")};
for (auto& character : imageTypes) {
if (std::isspace(character))
character = ',';
}
imageTypes = Utils::String::replace(imageTypes, ",,", ",");
mThemeImageTypes = Utils::String::delimitedStringToVector(imageTypes, ",");
}
if (properties & COLOR) {
if (elem->has("color"))

View file

@ -24,7 +24,7 @@ public:
// Loads the image at the given filepath. Will tile if tile is true (retrieves texture
// as tiling, creates vertices accordingly).
void setImage(const std::string& path, bool tile = false);
void setImage(const std::string& path, bool tile = false) override;
// Loads an image from memory.
void setImage(const char* data, size_t length, bool tile = false);
// Use an already existing texture.

View file

@ -12,6 +12,7 @@
#include "Window.h"
#include "resources/ResourceManager.h"
#include "utils/FileSystemUtil.h"
#include "utils/StringUtil.h"
#include <SDL2/SDL_timer.h>
@ -80,12 +81,17 @@ bool VideoComponent::setVideo(std::string path)
void VideoComponent::setImage(const std::string& path, bool tile)
{
std::string imagePath {path};
if (imagePath == "")
imagePath = mDefaultImagePath;
// Check that the image has changed.
if (path == mStaticImagePath)
if (imagePath == mStaticImagePath)
return;
mStaticImage.setImage(path, tile);
mStaticImagePath = path;
mStaticImage.setImage(imagePath, tile);
mStaticImagePath = imagePath;
}
void VideoComponent::onShow()
@ -268,6 +274,7 @@ void VideoComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
if (elem->has("defaultImage")) {
mStaticImage.setDefaultImage(elem->get<std::string>("defaultImage"));
mStaticImage.setImage(mStaticImagePath);
mDefaultImagePath = elem->get<std::string>("defaultImage");
}
if (elem->has("path"))
@ -287,8 +294,15 @@ void VideoComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
else if (elem->has("showSnapshotDelay"))
mConfig.showSnapshotDelay = elem->get<bool>("showSnapshotDelay");
if (properties & METADATA && elem->has("imageType"))
mThemeImageType = elem->get<std::string>("imageType");
if (properties && elem->has("imageType")) {
std::string imageTypes {elem->get<std::string>("imageType")};
for (auto& character : imageTypes) {
if (std::isspace(character))
character = ',';
}
imageTypes = Utils::String::replace(imageTypes, ",,", ",");
mThemeImageTypes = Utils::String::delimitedStringToVector(imageTypes, ",");
}
if (elem->has("pillarboxes"))
mDrawPillarboxes = elem->get<bool>("pillarboxes");

View file

@ -40,7 +40,7 @@ public:
// Configures the component to show the static video.
void setStaticVideo() { setVideo(mConfig.staticVideoPath); }
// Loads a static image that is displayed if the video cannot be played.
void setImage(const std::string& path, bool tile = false);
void setImage(const std::string& path, bool tile = false) override;
// Sets whether we're in media viewer mode.
void setMediaViewerMode(bool isMediaViewer) { mMediaViewerMode = isMediaViewer; }
// Sets whether we're in screensaver mode.
@ -125,6 +125,7 @@ protected:
glm::vec2 mVideoAreaSize;
std::shared_ptr<TextureResource> mTexture;
std::string mStaticImagePath;
std::string mDefaultImagePath;
std::string mVideoPath;
std::string mPlayingVideoPath;