diff --git a/NEWS.md b/NEWS.md index fc7ae3f0c..a6a06a9f4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -80,6 +80,7 @@ Many bugs have been fixed, and numerous features that were only partially implem * Deleting a game from the metadata editor did not delete the game media files or the entry in the gamelist.xml file * SystemView didn't properly loop the systems if only two systems were available * Hidden files still showed up if they had a gamelist.xml entry +* Fixed an annoying gamelist issue that caused the game images and data to be updated and rendered up to six times every time the list was scrolled * VRAM statistics overlay was somewhat broken and incorrectly displayed numbers in megabytes instead of mebibytes * On Unix, adding a hidden folder with a game in it crashed the application on startup * If the user tried to enter a blank game name in the metadata editor, the application would crash upon saving diff --git a/es-app/src/views/gamelist/DetailedGameListView.cpp b/es-app/src/views/gamelist/DetailedGameListView.cpp index 4b2075cd3..50bf51310 100644 --- a/es-app/src/views/gamelist/DetailedGameListView.cpp +++ b/es-app/src/views/gamelist/DetailedGameListView.cpp @@ -9,6 +9,9 @@ #include "animations/LambdaAnimation.h" #include "views/ViewController.h" +#define FADE_IN_START_OPACITY 0.5f +#define FADE_IN_TIME 300 + DetailedGameListView::DetailedGameListView( Window* window, FileData* root) @@ -37,7 +40,8 @@ DetailedGameListView::DetailedGameListView( mPlayers(window), mLastPlayed(window), mPlayCount(window), - mName(window) + mName(window), + mLastUpdated(nullptr) { const float padding = 0.01f; @@ -233,6 +237,13 @@ void DetailedGameListView::initMDValues() void DetailedGameListView::updateInfoPanel() { FileData* file = (mList.size() == 0 || mList.isScrolling()) ? nullptr : mList.getSelected(); + + // If the game data has already been rendered to the info panel, then skip it this time. + if (file == mLastUpdated) { + return; + } + mLastUpdated = file; + bool hideMetaDataFields = false; if (file) @@ -277,14 +288,20 @@ void DetailedGameListView::updateInfoPanel() bool fadingOut; if (file == nullptr) { - //mImage.setImage(""); - //mDescription.setText(""); fadingOut = true; } else { mThumbnail.setImage(file->getThumbnailPath()); mMarquee.setImage(file->getMarqueePath()); mImage.setImage(file->getImagePath()); + + // Fade in the game image. + auto func = [this](float t) { + mImage.setOpacity((unsigned char)(Math::lerp( + static_cast(FADE_IN_START_OPACITY), 1.0f, t)*255)); + }; + mImage.setAnimation(new LambdaAnimation(func, FADE_IN_TIME), 0, nullptr, false); + mDescription.setText(file->metadata.get("desc")); mDescContainer.reset(); diff --git a/es-app/src/views/gamelist/DetailedGameListView.h b/es-app/src/views/gamelist/DetailedGameListView.h index a66a5b861..03a9c59ac 100644 --- a/es-app/src/views/gamelist/DetailedGameListView.h +++ b/es-app/src/views/gamelist/DetailedGameListView.h @@ -4,7 +4,6 @@ // Interface that defines a GameListView of the type 'detailed'. // -#pragma once #ifndef ES_APP_VIEWS_GAME_LIST_DETAILED_GAME_LIST_VIEW_H #define ES_APP_VIEWS_GAME_LIST_DETAILED_GAME_LIST_VIEW_H @@ -58,6 +57,8 @@ private: ScrollableContainer mDescContainer; TextComponent mDescription; + + FileData* mLastUpdated; }; #endif // ES_APP_VIEWS_GAME_LIST_DETAILED_GAME_LIST_VIEW_H diff --git a/es-app/src/views/gamelist/VideoGameListView.cpp b/es-app/src/views/gamelist/VideoGameListView.cpp index b8c5f1a54..f0ba12745 100644 --- a/es-app/src/views/gamelist/VideoGameListView.cpp +++ b/es-app/src/views/gamelist/VideoGameListView.cpp @@ -81,15 +81,6 @@ VideoGameListView::VideoGameListView( mMarquee.setDefaultZIndex(35); addChild(&mMarquee); - // Image. - mImage.setOrigin(0.5f, 0.5f); - // Default to off the screen. - mImage.setPosition(mSize.x() * 0.25f, mList.getPosition().y() + mSize.y() * 0.2125f); - mImage.setVisible(false); - mImage.setMaxSize(mSize.x() * (0.50f - 2*padding), mSize.y() * 0.4f); - mImage.setDefaultZIndex(30); - addChild(&mImage); - // Video. mVideo->setOrigin(0.5f, 0.5f); mVideo->setPosition(mSize.x() * 0.25f, mSize.y() * 0.4f); @@ -265,10 +256,16 @@ void VideoGameListView::initMDValues() void VideoGameListView::updateInfoPanel() { FileData* file = (mList.size() == 0 || mList.isScrolling()) ? nullptr : mList.getSelected(); - bool hideMetaDataFields = false; - Utils::FileSystem::removeFile(getTitlePath()); + // If the game data has already been rendered to the info panel, then skip it this time. + if (file == mLastUpdated) { + return; + } + mLastUpdated = file; + + bool hideMetaDataFields = false; + if (file) hideMetaDataFields = (file->metadata.get("hidemetadata") == "true"); @@ -314,8 +311,6 @@ void VideoGameListView::updateInfoPanel() mVideo->setVideo(""); mVideo->setImage(""); mVideoPlaying = false; - //mMarquee.setImage(""); - //mDescription.setText(""); fadingOut = true; } diff --git a/es-app/src/views/gamelist/VideoGameListView.h b/es-app/src/views/gamelist/VideoGameListView.h index fc42672f0..1a1e19e45 100644 --- a/es-app/src/views/gamelist/VideoGameListView.h +++ b/es-app/src/views/gamelist/VideoGameListView.h @@ -4,7 +4,6 @@ // Interface that defines a GameListView of the type 'video'. // -#pragma once #ifndef ES_APP_VIEWS_GAME_LIST_VIDEO_GAME_LIST_VIEW_H #define ES_APP_VIEWS_GAME_LIST_VIDEO_GAME_LIST_VIEW_H @@ -22,9 +21,7 @@ public: virtual ~VideoGameListView(); virtual void onShow() override; - virtual void onThemeChanged(const std::shared_ptr& theme) override; - virtual const char* getName() const override { return "video"; } virtual void launch(FileData* game) override; @@ -68,6 +65,7 @@ private: TextComponent mDescription; bool mVideoPlaying; + FileData* mLastUpdated; }; #endif // ES_APP_VIEWS_GAME_LIST_VIDEO_GAME_LIST_VIEW_H