Add image slideshow screensaver mode

This change adds an image slideshow screensaver mode with optional
background audio.  The existing menu and video screensaver have been
refactored to include this new mode.

By default, the slideshow screensaver will show images from the
game list, but it can be configured in the menu to use a custom
directory instead.
This commit is contained in:
sal 2017-09-08 21:45:50 -06:00
parent 85ebeb524e
commit ddf94786f4
14 changed files with 697 additions and 215 deletions

View file

@ -26,6 +26,9 @@ set(ES_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiGameScraper.h ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiGameScraper.h
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiGamelistOptions.h ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiGamelistOptions.h
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiScreensaverOptions.h ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiScreensaverOptions.h
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiGeneralScreensaverOptions.h
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiVideoScreensaverOptions.h
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiSlideshowScreensaverOptions.h
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMenu.h ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMenu.h
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiSettings.h ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiSettings.h
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiScraperMulti.h ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiScraperMulti.h
@ -79,6 +82,9 @@ set(ES_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiGameScraper.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiGameScraper.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiGamelistOptions.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiGamelistOptions.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiScreensaverOptions.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiScreensaverOptions.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiGeneralScreensaverOptions.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiVideoScreensaverOptions.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiSlideshowScreensaverOptions.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMenu.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMenu.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiSettings.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiSettings.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiScraperMulti.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiScraperMulti.cpp

View file

@ -3,6 +3,7 @@
#include "components/VideoPlayerComponent.h" #include "components/VideoPlayerComponent.h"
#endif #endif
#include "components/VideoVlcComponent.h" #include "components/VideoVlcComponent.h"
#include "components/ImageComponent.h"
#include "platform.h" #include "platform.h"
#include "PowerSaver.h" #include "PowerSaver.h"
#include "Renderer.h" #include "Renderer.h"
@ -10,6 +11,8 @@
#include "SystemData.h" #include "SystemData.h"
#include "Util.h" #include "Util.h"
#include "Log.h" #include "Log.h"
#include "AudioManager.h"
#include "Sound.h"
#include "views/ViewController.h" #include "views/ViewController.h"
#include "views/gamelist/IGameListView.h" #include "views/gamelist/IGameListView.h"
#include <stdio.h> #include <stdio.h>
@ -18,15 +21,19 @@
SystemScreenSaver::SystemScreenSaver(Window* window) : SystemScreenSaver::SystemScreenSaver(Window* window) :
mVideoScreensaver(NULL), mVideoScreensaver(NULL),
mImageScreensaver(NULL),
mWindow(window), mWindow(window),
mCounted(false), mVideosCounted(false),
mVideoCount(0), mVideoCount(0),
mImagesCounted(false),
mImageCount(0),
mState(STATE_INACTIVE), mState(STATE_INACTIVE),
mOpacity(0.0f), mOpacity(0.0f),
mTimer(0), mTimer(0),
mSystemName(""), mSystemName(""),
mGameName(""), mGameName(""),
mCurrentGame(NULL) mCurrentGame(NULL),
mStopBackgroundAudio(true)
{ {
mWindow->setScreenSaver(this); mWindow->setScreenSaver(this);
std::string path = getTitleFolder(); std::string path = getTitleFolder();
@ -42,12 +49,13 @@ SystemScreenSaver::~SystemScreenSaver()
remove(getTitlePath().c_str()); remove(getTitlePath().c_str());
mCurrentGame = NULL; mCurrentGame = NULL;
delete mVideoScreensaver; delete mVideoScreensaver;
delete mImageScreensaver;
} }
bool SystemScreenSaver::allowSleep() bool SystemScreenSaver::allowSleep()
{ {
//return false; //return false;
return (mVideoScreensaver == NULL); return ((mVideoScreensaver == NULL) && (mImageScreensaver == NULL));
} }
bool SystemScreenSaver::isScreenSaverActive() bool SystemScreenSaver::isScreenSaverActive()
@ -57,7 +65,8 @@ bool SystemScreenSaver::isScreenSaverActive()
void SystemScreenSaver::startScreenSaver() void SystemScreenSaver::startScreenSaver()
{ {
if (!mVideoScreensaver && (Settings::getInstance()->getString("ScreenSaverBehavior") == "random video")) std::string screensaver_behavior = Settings::getInstance()->getString("ScreenSaverBehavior");
if (!mVideoScreensaver && (screensaver_behavior == "random video"))
{ {
// Configure to fade out the windows, Skip Fading if Instant mode // Configure to fade out the windows, Skip Fading if Instant mode
mState = PowerSaver::getMode() == PowerSaver::INSTANT mState = PowerSaver::getMode() == PowerSaver::INSTANT
@ -79,9 +88,8 @@ void SystemScreenSaver::startScreenSaver()
if (!path.empty() && boost::filesystem::exists(path)) if (!path.empty() && boost::filesystem::exists(path))
{ {
// Create the correct type of video component
#ifdef _RPI_ #ifdef _RPI_
// Create the correct type of video component
if (Settings::getInstance()->getBool("ScreenSaverOmxPlayer")) if (Settings::getInstance()->getBool("ScreenSaverOmxPlayer"))
mVideoScreensaver = new VideoPlayerComponent(mWindow, getTitlePath()); mVideoScreensaver = new VideoPlayerComponent(mWindow, getTitlePath());
else else
@ -109,6 +117,64 @@ void SystemScreenSaver::startScreenSaver()
return; return;
} }
} }
else if (screensaver_behavior == "slideshow")
{
// Configure to fade out the windows, Skip Fading if Instant mode
mState = PowerSaver::getMode() == PowerSaver::INSTANT
? STATE_SCREENSAVER_ACTIVE
: STATE_FADE_OUT_WINDOW;
mVideoChangeTime = Settings::getInstance()->getInt("ScreenSaverSwapImageTimeout");
mOpacity = 0.0f;
// Load a random image
std::string path = "";
if (Settings::getInstance()->getBool("SlideshowScreenSaverCustomImageSource"))
{
pickRandomCustomImage(path);
// Custom images are not tied to the game list
mCurrentGame = NULL;
}
else
{
pickRandomGameListImage(path);
}
if (!mImageScreensaver)
{
mImageScreensaver = new ImageComponent(mWindow, false, false);
}
mTimer = 0;
mImageScreensaver->setImage(path);
mImageScreensaver->setOrigin(0.5f, 0.5f);
mImageScreensaver->setPosition(Renderer::getScreenWidth()/2, Renderer::getScreenHeight()/2);
if (Settings::getInstance()->getBool("SlideshowScreenSaverStretch"))
{
mImageScreensaver->setResize((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight());
}
else
{
mImageScreensaver->setMaxSize((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight());
}
std::string bg_audio_file = Settings::getInstance()->getString("SlideshowScreenSaverBackgroundAudioFile");
if ((!mBackgroundAudio) && (bg_audio_file != ""))
{
if (boost::filesystem::exists(bg_audio_file))
{
// paused PS so that the background audio keeps playing
PowerSaver::pause();
mBackgroundAudio = Sound::get(bg_audio_file);
mBackgroundAudio->play();
}
}
PowerSaver::runningScreenSaver(true);
mTimer = 0;
return;
}
// No videos. Just use a standard screensaver // No videos. Just use a standard screensaver
mState = STATE_SCREENSAVER_ACTIVE; mState = STATE_SCREENSAVER_ACTIVE;
mCurrentGame = NULL; mCurrentGame = NULL;
@ -116,8 +182,22 @@ void SystemScreenSaver::startScreenSaver()
void SystemScreenSaver::stopScreenSaver() void SystemScreenSaver::stopScreenSaver()
{ {
if ((mBackgroundAudio) && (mStopBackgroundAudio))
{
mBackgroundAudio->stop();
mBackgroundAudio.reset();
// if we were playing audio, we paused PS
PowerSaver::resume();
}
// so that we stop the background audio next time, unless we're restarting the screensaver
mStopBackgroundAudio = true;
delete mVideoScreensaver; delete mVideoScreensaver;
mVideoScreensaver = NULL; mVideoScreensaver = NULL;
delete mImageScreensaver;
mImageScreensaver = NULL;
// we need this to loop through different videos // we need this to loop through different videos
mState = STATE_INACTIVE; mState = STATE_INACTIVE;
PowerSaver::runningScreenSaver(false); PowerSaver::runningScreenSaver(false);
@ -125,7 +205,8 @@ void SystemScreenSaver::stopScreenSaver()
void SystemScreenSaver::renderScreenSaver() void SystemScreenSaver::renderScreenSaver()
{ {
if (mVideoScreensaver && Settings::getInstance()->getString("ScreenSaverBehavior") == "random video") std::string screensaver_behavior = Settings::getInstance()->getString("ScreenSaverBehavior");
if (mVideoScreensaver && screensaver_behavior == "random video")
{ {
// Render black background // Render black background
Renderer::setMatrix(Eigen::Affine3f::Identity()); Renderer::setMatrix(Eigen::Affine3f::Identity());
@ -138,59 +219,49 @@ void SystemScreenSaver::renderScreenSaver()
mVideoScreensaver->render(transform); mVideoScreensaver->render(transform);
} }
} }
else if (mImageScreensaver && screensaver_behavior == "slideshow")
{
// Render black background
Renderer::setMatrix(Eigen::Affine3f::Identity());
Renderer::drawRect(0, 0, Renderer::getScreenWidth(), Renderer::getScreenHeight(), (unsigned char)(255));
// Only render the video if the state requires it
if ((int)mState >= STATE_FADE_IN_VIDEO)
{
if (mImageScreensaver->hasImage())
{
mImageScreensaver->setOpacity(255-mOpacity);
Eigen::Affine3f transform = Eigen::Affine3f::Identity();
mImageScreensaver->render(transform);
}
}
// Check if we need to restart the background audio
if ((mBackgroundAudio) && (Settings::getInstance()->getString("SlideshowScreenSaverBackgroundAudioFile") != ""))
{
if (!mBackgroundAudio->isPlaying())
{
mBackgroundAudio->play();
}
}
}
else if (mState != STATE_INACTIVE) else if (mState != STATE_INACTIVE)
{ {
Renderer::setMatrix(Eigen::Affine3f::Identity()); Renderer::setMatrix(Eigen::Affine3f::Identity());
unsigned char opacity = Settings::getInstance()->getString("ScreenSaverBehavior") == "dim" ? 0xA0 : 0xFF; unsigned char opacity = screensaver_behavior == "dim" ? 0xA0 : 0xFF;
Renderer::drawRect(0, 0, Renderer::getScreenWidth(), Renderer::getScreenHeight(), 0x00000000 | opacity); Renderer::drawRect(0, 0, Renderer::getScreenWidth(), Renderer::getScreenHeight(), 0x00000000 | opacity);
} }
} }
void SystemScreenSaver::countVideos() unsigned long SystemScreenSaver::countGameListNodes(const char *nodeName)
{ {
if (!mCounted) unsigned long nodeCount = 0;
std::vector<SystemData*>:: iterator it;
for (it = SystemData::sSystemVector.begin(); it != SystemData::sSystemVector.end(); ++it)
{ {
mVideoCount = 0; // We only want images and videos from game systems that are not collections
mCounted = true; if (!(*it)->isCollection() && (*it)->isGameSystem())
std::vector<SystemData*>:: iterator it;
for (it = SystemData::sSystemVector.begin(); it != SystemData::sSystemVector.end(); ++it)
{
if (!(*it)->isCollection())
{
pugi::xml_document doc;
pugi::xml_node root;
std::string xmlReadPath = (*it)->getGamelistPath(false);
if(boost::filesystem::exists(xmlReadPath))
{
pugi::xml_parse_result result = doc.load_file(xmlReadPath.c_str());
if (!result)
continue;
root = doc.child("gameList");
if (!root)
continue;
for(pugi::xml_node fileNode = root.child("game"); fileNode; fileNode = fileNode.next_sibling("game"))
{
pugi::xml_node videoNode = fileNode.child("video");
if (videoNode)
++mVideoCount;
}
}
}
}
}
}
void SystemScreenSaver::pickRandomVideo(std::string& path)
{
countVideos();
mCurrentGame = NULL;
if (mVideoCount > 0)
{
int video = (int)(((float)rand() / float(RAND_MAX)) * (float)mVideoCount);
std::vector<SystemData*>:: iterator it;
for (it = SystemData::sSystemVector.begin(); it != SystemData::sSystemVector.end(); ++it)
{ {
pugi::xml_document doc; pugi::xml_document doc;
pugi::xml_node root; pugi::xml_node root;
@ -206,58 +277,109 @@ void SystemScreenSaver::pickRandomVideo(std::string& path)
continue; continue;
for(pugi::xml_node fileNode = root.child("game"); fileNode; fileNode = fileNode.next_sibling("game")) for(pugi::xml_node fileNode = root.child("game"); fileNode; fileNode = fileNode.next_sibling("game"))
{ {
pugi::xml_node videoNode = fileNode.child("video"); pugi::xml_node node = fileNode.child(nodeName);
if (videoNode) if (node)
++nodeCount;
}
}
}
}
return nodeCount;
}
void SystemScreenSaver::countVideos()
{
if (!mVideosCounted)
{
mVideoCount = countGameListNodes("video");
mVideosCounted = true;
}
}
void SystemScreenSaver::countImages()
{
if (!mImagesCounted)
{
mImageCount = countGameListNodes("image");
mImagesCounted = true;
}
}
void SystemScreenSaver::pickGameListNode(unsigned long index, const char *nodeName, std::string& path)
{
std::vector<SystemData*>:: iterator it;
for (it = SystemData::sSystemVector.begin(); it != SystemData::sSystemVector.end(); ++it)
{
pugi::xml_document doc;
pugi::xml_node root;
// We only want nodes from game systems that are not collections
if (!(*it)->isGameSystem() || (*it)->isCollection())
continue;
std::string xmlReadPath = (*it)->getGamelistPath(false);
if(boost::filesystem::exists(xmlReadPath))
{
pugi::xml_parse_result result = doc.load_file(xmlReadPath.c_str());
if (!result)
continue;
root = doc.child("gameList");
if (!root)
continue;
for(pugi::xml_node fileNode = root.child("game"); fileNode; fileNode = fileNode.next_sibling("game"))
{
pugi::xml_node node = fileNode.child(nodeName);
if (node)
{
// See if this is the desired index
if (index-- == 0)
{ {
// See if this is the randomly selected video // Yes. Resolve to a full path
if (video-- == 0) path = resolvePath(node.text().get(), (*it)->getStartPath(), true).generic_string();
mSystemName = (*it)->getFullName();
mGameName = fileNode.child("name").text().get();
// getting corresponding FileData
// try the easy way. Should work for the majority of cases, unless in subfolders
FileData* rootFileData = (*it)->getRootFolder();
std::string gamePath = resolvePath(fileNode.child("path").text().get(), (*it)->getStartPath(), false).string();
std::string shortPath = gamePath;
shortPath = shortPath.replace(0, (*it)->getStartPath().length()+1, "");
const std::unordered_map<std::string, FileData*>& children = rootFileData->getChildrenByFilename();
std::unordered_map<std::string, FileData*>::const_iterator screenSaverGame = children.find(shortPath);
if (screenSaverGame != children.end())
{ {
// Yes. Resolve to a full path // Found the corresponding FileData
path = resolvePath(videoNode.text().get(), (*it)->getStartPath(), true).generic_string(); mCurrentGame = screenSaverGame->second;
mSystemName = (*it)->getFullName(); }
mGameName = fileNode.child("name").text().get(); else
{
// Couldn't find FileData. Going for the full iteration.
// iterate on children
FileType type = GAME;
std::vector<FileData*> allFiles = rootFileData->getFilesRecursive(type);
std::vector<FileData*>::iterator itf; // declare an iterator to a vector of strings
// getting corresponding FileData int i = 0;
for(itf=allFiles.begin() ; itf < allFiles.end(); itf++,i++ ) {
// try the easy way. Should work for the majority of cases, unless in subfolders if ((*itf)->getPath() == gamePath)
FileData* rootFileData = (*it)->getRootFolder(); {
std::string gamePath = resolvePath(fileNode.child("path").text().get(), (*it)->getStartPath(), false).string(); mCurrentGame = (*itf);
break;
std::string shortPath = gamePath;
shortPath = shortPath.replace(0, (*it)->getStartPath().length()+1, "");
const std::unordered_map<std::string, FileData*>& children = rootFileData->getChildrenByFilename();
std::unordered_map<std::string, FileData*>::const_iterator screenSaverGame = children.find(shortPath);
if (screenSaverGame != children.end())
{
// Found the corresponding FileData
mCurrentGame = screenSaverGame->second;
}
else
{
// Couldn't find FileData. Going for the full iteration.
// iterate on children
FileType type = GAME;
std::vector<FileData*> allFiles = rootFileData->getFilesRecursive(type);
std::vector<FileData*>::iterator itf; // declare an iterator to a vector of strings
int i = 0;
for(itf=allFiles.begin() ; itf < allFiles.end(); itf++,i++ ) {
if ((*itf)->getPath() == gamePath)
{
mCurrentGame = (*itf);
break;
}
} }
} }
// end of getting FileData
if (Settings::getInstance()->getString("ScreenSaverGameInfo") != "never")
writeSubtitle(mGameName.c_str(), mSystemName.c_str(),
(Settings::getInstance()->getString("ScreenSaverGameInfo") == "always"));
return;
} }
// end of getting FileData
if (Settings::getInstance()->getString("ScreenSaverGameInfo") != "never")
writeSubtitle(mGameName.c_str(), mSystemName.c_str(),
(Settings::getInstance()->getString("ScreenSaverGameInfo") == "always"));
return;
} }
} }
} }
@ -265,6 +387,97 @@ void SystemScreenSaver::pickRandomVideo(std::string& path)
} }
} }
void SystemScreenSaver::pickRandomVideo(std::string& path)
{
countVideos();
mCurrentGame = NULL;
if (mVideoCount > 0)
{
int video = (int)(((float)rand() / float(RAND_MAX)) * (float)mVideoCount);
pickGameListNode(video, "video", path);
}
}
void SystemScreenSaver::pickRandomGameListImage(std::string& path)
{
countImages();
mCurrentGame = NULL;
if (mImageCount > 0)
{
int image = (int)(((float)rand() / float(RAND_MAX)) * (float)mImageCount);
pickGameListNode(image, "image", path);
}
}
void SystemScreenSaver::pickRandomCustomImage(std::string& path)
{
std::string imageDir = Settings::getInstance()->getString("SlideshowScreenSaverImageDir");
if ((imageDir != "") && (boost::filesystem::exists(imageDir)))
{
std::string imageFilter = Settings::getInstance()->getString("SlideshowScreenSaverImageFilter");
std::vector<std::string> matchingFiles;
if (Settings::getInstance()->getBool("SlideshowScreenSaverRecurse"))
{
boost::filesystem::recursive_directory_iterator end_iter;
boost::filesystem::recursive_directory_iterator iter(imageDir);
// TODO: Figure out how to remove this duplication in the else block
for (iter; iter != end_iter; ++iter)
{
if (boost::filesystem::is_regular_file(iter->status()))
{
// If the image filter is empty, or the file extension is in the filter string,
// add it to the matching files list
if ((imageFilter.length() <= 0) ||
(imageFilter.find(iter->path().extension().string()) != std::string::npos))
{
matchingFiles.push_back(iter->path().string());
}
}
}
}
else
{
boost::filesystem::directory_iterator end_iter;
boost::filesystem::directory_iterator iter(imageDir);
for (iter; iter != end_iter; ++iter)
{
if (boost::filesystem::is_regular_file(iter->status()))
{
// If the image filter is empty, or the file extension is in the filter string,
// add it to the matching files list
if ((imageFilter.length() <= 0) ||
(imageFilter.find(iter->path().extension().string()) != std::string::npos))
{
matchingFiles.push_back(iter->path().string());
}
}
}
}
int fileCount = matchingFiles.size();
if (fileCount > 0)
{
// get a random index in the range 0 to fileCount (exclusive)
int randomIndex = rand() % fileCount;
path = matchingFiles[randomIndex];
}
else
{
LOG(LogError) << "Slideshow Screensaver - No image files found\n";
}
}
else
{
LOG(LogError) << "Slideshow Screensaver - Image directory does not exist: " << imageDir << "\n";
}
}
void SystemScreenSaver::update(int deltaTime) void SystemScreenSaver::update(int deltaTime)
{ {
// Use this to update the fade value for the current fade stage // Use this to update the fade value for the current fade stage
@ -302,9 +515,12 @@ void SystemScreenSaver::update(int deltaTime)
// If we have a loaded video then update it // If we have a loaded video then update it
if (mVideoScreensaver) if (mVideoScreensaver)
mVideoScreensaver->update(deltaTime); mVideoScreensaver->update(deltaTime);
if (mImageScreensaver)
mImageScreensaver->update(deltaTime);
} }
void SystemScreenSaver::nextVideo() { void SystemScreenSaver::nextVideo() {
mStopBackgroundAudio = false;
stopScreenSaver(); stopScreenSaver();
startScreenSaver(); startScreenSaver();
mState = STATE_SCREENSAVER_ACTIVE; mState = STATE_SCREENSAVER_ACTIVE;
@ -317,12 +533,15 @@ FileData* SystemScreenSaver::getCurrentGame()
void SystemScreenSaver::launchGame() void SystemScreenSaver::launchGame()
{ {
// launching Game if (mCurrentGame != NULL)
ViewController::get()->goToGameList(mCurrentGame->getSystem());
IGameListView* view = ViewController::get()->getGameListView(mCurrentGame->getSystem()).get();
view->setCursor(mCurrentGame);
if (Settings::getInstance()->getBool("ScreenSaverControls"))
{ {
view->launch(mCurrentGame); // launching Game
ViewController::get()->goToGameList(mCurrentGame->getSystem());
IGameListView* view = ViewController::get()->getGameListView(mCurrentGame->getSystem()).get();
view->setCursor(mCurrentGame);
if (Settings::getInstance()->getBool("ScreenSaverControls"))
{
view->launch(mCurrentGame);
}
} }
} }

View file

@ -3,6 +3,8 @@
#include "Window.h" #include "Window.h"
class VideoComponent; class VideoComponent;
class ImageComponent;
class Sound;
// Screensaver implementation for main window // Screensaver implementation for main window
class SystemScreenSaver : public Window::ScreenSaver class SystemScreenSaver : public Window::ScreenSaver
@ -23,8 +25,13 @@ public:
virtual void launchGame(); virtual void launchGame();
private: private:
void countVideos(); unsigned long countGameListNodes(const char *nodeName);
void pickRandomVideo(std::string& path); void countVideos();
void countImages();
void pickGameListNode(unsigned long index, const char *nodeName, std::string& path);
void pickRandomVideo(std::string& path);
void pickRandomGameListImage(std::string& path);
void pickRandomCustomImage(std::string& path);
void input(InputConfig* config, Input input); void input(InputConfig* config, Input input);
@ -36,9 +43,12 @@ private:
}; };
private: private:
bool mCounted; bool mVideosCounted;
unsigned long mVideoCount; unsigned long mVideoCount;
VideoComponent* mVideoScreensaver; VideoComponent* mVideoScreensaver;
bool mImagesCounted;
unsigned long mImageCount;
ImageComponent* mImageScreensaver;
Window* mWindow; Window* mWindow;
STATE mState; STATE mState;
float mOpacity; float mOpacity;
@ -47,4 +57,6 @@ private:
std::string mGameName; std::string mGameName;
std::string mSystemName; std::string mSystemName;
int mVideoChangeTime; int mVideoChangeTime;
std::shared_ptr<Sound> mBackgroundAudio;
bool mStopBackgroundAudio;
}; };

View file

@ -0,0 +1,77 @@
#include "guis/GuiGeneralScreensaverOptions.h"
#include "Window.h"
#include "Settings.h"
#include "PowerSaver.h"
#include "views/ViewController.h"
#include "components/ButtonComponent.h"
#include "components/SwitchComponent.h"
#include "components/SliderComponent.h"
#include "components/TextComponent.h"
//#include "components/TextEditComponent.h"
#include "components/OptionListComponent.h"
#include "components/MenuComponent.h"
#include "guis/GuiMsgBox.h"
#include "guis/GuiVideoScreensaverOptions.h"
#include "guis/GuiSlideshowScreensaverOptions.h"
GuiGeneralScreensaverOptions::GuiGeneralScreensaverOptions(Window* window, const char* title) : GuiScreensaverOptions(window, title)
{
// screensaver time
auto screensaver_time = std::make_shared<SliderComponent>(mWindow, 0.f, 30.f, 1.f, "m");
screensaver_time->setValue((float)(Settings::getInstance()->getInt("ScreenSaverTime") / (1000 * 60)));
addWithLabel("SCREENSAVER AFTER", screensaver_time);
addSaveFunc([screensaver_time] {
Settings::getInstance()->setInt("ScreenSaverTime", (int)round(screensaver_time->getValue()) * (1000 * 60));
PowerSaver::updateTimeouts();
});
// screensaver behavior
auto screensaver_behavior = std::make_shared< OptionListComponent<std::string> >(mWindow, "SCREENSAVER BEHAVIOR", false);
std::vector<std::string> screensavers;
screensavers.push_back("dim");
screensavers.push_back("black");
screensavers.push_back("random video");
screensavers.push_back("slideshow");
for(auto it = screensavers.begin(); it != screensavers.end(); it++)
screensaver_behavior->add(*it, *it, Settings::getInstance()->getString("ScreenSaverBehavior") == *it);
addWithLabel("SCREENSAVER BEHAVIOR", screensaver_behavior);
addSaveFunc([this, screensaver_behavior] {
if (Settings::getInstance()->getString("ScreenSaverBehavior") != "random video" && screensaver_behavior->getSelected() == "random video") {
// if before it wasn't risky but now there's a risk of problems, show warning
mWindow->pushGui(new GuiMsgBox(mWindow,
"The \"Random Video\" screensaver shows videos from your gamelist.\n\nIf you do not have videos, or if in several consecutive attempts the games it selects don't have videos it will default to black.\n\nMore options in the \"UI Settings\" > \"Video Screensaver\" menu.",
"OK", [] { return; }));
}
Settings::getInstance()->setString("ScreenSaverBehavior", screensaver_behavior->getSelected());
PowerSaver::updateTimeouts();
});
ComponentListRow row;
// show filtered menu
row.elements.clear();
row.addElement(std::make_shared<TextComponent>(mWindow, "VIDEO SCREENSAVER SETTINGS", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true);
row.addElement(makeArrow(mWindow), false);
row.makeAcceptInputHandler(std::bind(&GuiGeneralScreensaverOptions::openVideoScreensaverOptions, this));
addRow(row);
row.elements.clear();
row.addElement(std::make_shared<TextComponent>(mWindow, "SLIDESHOW SCREENSAVER SETTINGS", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true);
row.addElement(makeArrow(mWindow), false);
row.makeAcceptInputHandler(std::bind(&GuiGeneralScreensaverOptions::openSlideshowScreensaverOptions, this));
addRow(row);
}
GuiGeneralScreensaverOptions::~GuiGeneralScreensaverOptions()
{
}
void GuiGeneralScreensaverOptions::openVideoScreensaverOptions() {
mWindow->pushGui(new GuiVideoScreensaverOptions(mWindow, "VIDEO SCREENSAVER"));
}
void GuiGeneralScreensaverOptions::openSlideshowScreensaverOptions() {
mWindow->pushGui(new GuiSlideshowScreensaverOptions(mWindow, "SLIDESHOW SCREENSAVER"));
}

View file

@ -0,0 +1,18 @@
#ifndef _GUI_GENERAL_SCREENSAVER_OPTIONS_H_
#define _GUI_GENERAL_SCREENSAVER_OPTIONS_H_
#include "components/MenuComponent.h"
#include "GuiScreensaverOptions.h"
class GuiGeneralScreensaverOptions : public GuiScreensaverOptions
{
public:
GuiGeneralScreensaverOptions(Window* window, const char* title);
virtual ~GuiGeneralScreensaverOptions();
private:
void openVideoScreensaverOptions();
void openSlideshowScreensaverOptions();
};
#endif // _GUI_GENERAL_SCREENSAVER_OPTIONS_H_

View file

@ -7,7 +7,7 @@
#include "PowerSaver.h" #include "PowerSaver.h"
#include "guis/GuiMsgBox.h" #include "guis/GuiMsgBox.h"
#include "guis/GuiSettings.h" #include "guis/GuiSettings.h"
#include "guis/GuiScreensaverOptions.h" #include "guis/GuiGeneralScreensaverOptions.h"
#include "guis/GuiCollectionSystemsOptions.h" #include "guis/GuiCollectionSystemsOptions.h"
#include "guis/GuiScraperStart.h" #include "guis/GuiScraperStart.h"
#include "guis/GuiDetectDevice.h" #include "guis/GuiDetectDevice.h"
@ -132,42 +132,12 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN
[this] { [this] {
auto s = new GuiSettings(mWindow, "UI SETTINGS"); auto s = new GuiSettings(mWindow, "UI SETTINGS");
// screensaver time ComponentListRow screensaver_row;
auto screensaver_time = std::make_shared<SliderComponent>(mWindow, 0.f, 30.f, 1.f, "m"); screensaver_row.elements.clear();
screensaver_time->setValue((float)(Settings::getInstance()->getInt("ScreenSaverTime") / (1000 * 60))); screensaver_row.addElement(std::make_shared<TextComponent>(mWindow, "SCREENSAVER SETTINGS", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true);
s->addWithLabel("SCREENSAVER AFTER", screensaver_time); screensaver_row.addElement(makeArrow(mWindow), false);
s->addSaveFunc([screensaver_time] { screensaver_row.makeAcceptInputHandler(std::bind(&GuiMenu::openScreensaverOptions, this));
Settings::getInstance()->setInt("ScreenSaverTime", (int)round(screensaver_time->getValue()) * (1000 * 60)); s->addRow(screensaver_row);
PowerSaver::updateTimeouts();
});
// screensaver behavior
auto screensaver_behavior = std::make_shared< OptionListComponent<std::string> >(mWindow, "SCREENSAVER BEHAVIOR", false);
std::vector<std::string> screensavers;
screensavers.push_back("dim");
screensavers.push_back("black");
screensavers.push_back("random video");
for(auto it = screensavers.begin(); it != screensavers.end(); it++)
screensaver_behavior->add(*it, *it, Settings::getInstance()->getString("ScreenSaverBehavior") == *it);
s->addWithLabel("SCREENSAVER BEHAVIOR", screensaver_behavior);
s->addSaveFunc([this, screensaver_behavior] {
if (Settings::getInstance()->getString("ScreenSaverBehavior") != "random video" && screensaver_behavior->getSelected() == "random video") {
// if before it wasn't risky but now there's a risk of problems, show warning
mWindow->pushGui(new GuiMsgBox(mWindow,
"The \"Random Video\" screensaver shows videos from your gamelist.\n\nIf you do not have videos, or if in several consecutive attempts the games it selects don't have videos it will default to black.\n\nMore options in the \"UI Settings\" > \"Video Screensaver\" menu.",
"OK", [] { return; }));
}
Settings::getInstance()->setString("ScreenSaverBehavior", screensaver_behavior->getSelected());
});
ComponentListRow row;
// show filtered menu
row.elements.clear();
row.addElement(std::make_shared<TextComponent>(mWindow, "VIDEO SCREENSAVER SETTINGS", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true);
row.addElement(makeArrow(mWindow), false);
row.makeAcceptInputHandler(std::bind(&GuiMenu::openScreensaverOptions, this));
s->addRow(row);
// quick system select (left/right in game list view) // quick system select (left/right in game list view)
auto quick_sys_select = std::make_shared<SwitchComponent>(mWindow); auto quick_sys_select = std::make_shared<SwitchComponent>(mWindow);
@ -431,7 +401,7 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN
} }
void GuiMenu::openScreensaverOptions() { void GuiMenu::openScreensaverOptions() {
mWindow->pushGui(new GuiScreensaverOptions(mWindow, "VIDEO SCREENSAVER")); mWindow->pushGui(new GuiGeneralScreensaverOptions(mWindow, "SCREENSAVER SETTINGS"));
} }
void GuiMenu::openCollectionSystemSettings() { void GuiMenu::openCollectionSystemSettings() {

View file

@ -4,63 +4,11 @@
#include "views/ViewController.h" #include "views/ViewController.h"
#include "components/ButtonComponent.h" #include "components/ButtonComponent.h"
#include "components/SwitchComponent.h"
#include "components/SliderComponent.h"
#include "components/TextComponent.h"
#include "components/OptionListComponent.h"
#include "components/MenuComponent.h"
#include "guis/GuiMsgBox.h"
#include "PowerSaver.h"
GuiScreensaverOptions::GuiScreensaverOptions(Window* window, const char* title) : GuiComponent(window), mMenu(window, title) GuiScreensaverOptions::GuiScreensaverOptions(Window* window, const char* title) : GuiComponent(window), mMenu(window, title)
{ {
addChild(&mMenu); addChild(&mMenu);
// timeout to swap videos
auto swap = std::make_shared<SliderComponent>(mWindow, 10.f, 1000.f, 1.f, "s");
swap->setValue((float)(Settings::getInstance()->getInt("ScreenSaverSwapVideoTimeout") / (1000)));
addWithLabel("SWAP VIDEO AFTER (SECS)", swap);
addSaveFunc([swap] {
Settings::getInstance()->setInt("ScreenSaverSwapVideoTimeout", (int)round(swap->getValue()) * (1000));
PowerSaver::updateTimeouts();
});
#ifdef _RPI_
auto ss_omx = std::make_shared<SwitchComponent>(mWindow);
ss_omx->setState(Settings::getInstance()->getBool("ScreenSaverOmxPlayer"));
addWithLabel("USE OMX PLAYER FOR SCREENSAVER", ss_omx);
addSaveFunc([ss_omx, this] { Settings::getInstance()->setBool("ScreenSaverOmxPlayer", ss_omx->getState()); });
#endif
// Allow ScreenSaver Controls - ScreenSaverControls
auto ss_controls = std::make_shared<SwitchComponent>(mWindow);
ss_controls->setState(Settings::getInstance()->getBool("ScreenSaverControls"));
addWithLabel("SCREENSAVER CONTROLS", ss_controls);
addSaveFunc([ss_controls] { Settings::getInstance()->setBool("ScreenSaverControls", ss_controls->getState()); });
// Render Video Game Name as subtitles
auto ss_info = std::make_shared< OptionListComponent<std::string> >(mWindow, "SHOW GAME INFO", false);
std::vector<std::string> info_type;
info_type.push_back("always");
info_type.push_back("start & end");
info_type.push_back("never");
for(auto it = info_type.begin(); it != info_type.end(); it++)
ss_info->add(*it, *it, Settings::getInstance()->getString("ScreenSaverGameInfo") == *it);
addWithLabel("SHOW GAME INFO ON SCREENSAVER", ss_info);
addSaveFunc([ss_info, this] { Settings::getInstance()->setString("ScreenSaverGameInfo", ss_info->getSelected()); });
#ifndef _RPI_
auto captions_compatibility = std::make_shared<SwitchComponent>(mWindow);
captions_compatibility->setState(Settings::getInstance()->getBool("CaptionsCompatibility"));
addWithLabel("USE COMPATIBLE LOW RESOLUTION FOR CAPTIONS", captions_compatibility);
addSaveFunc([captions_compatibility] { Settings::getInstance()->setBool("CaptionsCompatibility", captions_compatibility->getState()); });
#endif
auto stretch_screensaver = std::make_shared<SwitchComponent>(mWindow);
stretch_screensaver->setState(Settings::getInstance()->getBool("StretchVideoOnScreenSaver"));
addWithLabel("STRETCH VIDEO ON SCREENSAVER", stretch_screensaver);
addSaveFunc([stretch_screensaver] { Settings::getInstance()->setBool("StretchVideoOnScreenSaver", stretch_screensaver->getState()); });
mMenu.addButton("BACK", "go back", [this] { delete this; }); mMenu.addButton("BACK", "go back", [this] { delete this; });
setSize((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight()); setSize((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight());
@ -77,24 +25,10 @@ void GuiScreensaverOptions::save()
if(!mSaveFuncs.size()) if(!mSaveFuncs.size())
return; return;
#ifdef _RPI_
bool startingStatusNotRisky = (Settings::getInstance()->getString("ScreenSaverGameInfo") == "never" || !Settings::getInstance()->getBool("ScreenSaverOmxPlayer"));
#endif
for(auto it = mSaveFuncs.begin(); it != mSaveFuncs.end(); it++) for(auto it = mSaveFuncs.begin(); it != mSaveFuncs.end(); it++)
(*it)(); (*it)();
Settings::getInstance()->saveFile(); Settings::getInstance()->saveFile();
#ifdef _RPI_
bool endStatusRisky = (Settings::getInstance()->getString("ScreenSaverGameInfo") != "never" && Settings::getInstance()->getBool("ScreenSaverOmxPlayer"));
if (startingStatusNotRisky && endStatusRisky) {
// if before it wasn't risky but now there's a risk of problems, show warning
mWindow->pushGui(new GuiMsgBox(mWindow,
"Using OMX Player and displaying Game Info may result in the video flickering in some TV modes. If that happens, consider:\n\n• Disabling the \"Show Game Info\" option;\n• Disabling \"Overscan\" on the Pi configuration menu might help:\nRetroPie > Raspi-Config > Advanced Options > Overscan > \"No\".\n• Disabling the use of OMX Player for the screensaver.",
"GOT IT!", [] { return; }));
}
#endif
} }
bool GuiScreensaverOptions::input(InputConfig* config, Input input) bool GuiScreensaverOptions::input(InputConfig* config, Input input)

View file

@ -1,3 +1,6 @@
#ifndef _GUI_SCREENSAVER_OPTIONS_H_
#define _GUI_SCREENSAVER_OPTIONS_H_
#include "GuiComponent.h" #include "GuiComponent.h"
#include "components/MenuComponent.h" #include "components/MenuComponent.h"
#include "SystemData.h" #include "SystemData.h"
@ -9,7 +12,7 @@ public:
GuiScreensaverOptions(Window* window, const char* title); GuiScreensaverOptions(Window* window, const char* title);
virtual ~GuiScreensaverOptions(); // just calls save(); virtual ~GuiScreensaverOptions(); // just calls save();
void save(); virtual void save();
inline void addRow(const ComponentListRow& row) { mMenu.addRow(row); }; inline void addRow(const ComponentListRow& row) { mMenu.addRow(row); };
inline void addWithLabel(const std::string& label, const std::shared_ptr<GuiComponent>& comp) { mMenu.addWithLabel(label, comp); }; inline void addWithLabel(const std::string& label, const std::shared_ptr<GuiComponent>& comp) { mMenu.addWithLabel(label, comp); };
inline void addSaveFunc(const std::function<void()>& func) { mSaveFuncs.push_back(func); }; inline void addSaveFunc(const std::function<void()>& func) { mSaveFuncs.push_back(func); };
@ -18,7 +21,9 @@ public:
std::vector<HelpPrompt> getHelpPrompts() override; std::vector<HelpPrompt> getHelpPrompts() override;
HelpStyle getHelpStyle() override; HelpStyle getHelpStyle() override;
private: protected:
MenuComponent mMenu; MenuComponent mMenu;
std::vector< std::function<void()> > mSaveFuncs; std::vector< std::function<void()> > mSaveFuncs;
}; };
#endif // _GUI_SCREENSAVER_OPTIONS_H_

View file

@ -0,0 +1,115 @@
#include "guis/GuiSlideshowScreensaverOptions.h"
#include "Window.h"
#include "Settings.h"
#include "views/ViewController.h"
#include "components/SwitchComponent.h"
#include "components/SliderComponent.h"
#include "components/TextComponent.h"
#include "components/OptionListComponent.h"
#include "components/MenuComponent.h"
#include "guis/GuiMsgBox.h"
#include "guis/GuiTextEditPopup.h"
#include "PowerSaver.h"
GuiSlideshowScreensaverOptions::GuiSlideshowScreensaverOptions(Window* window, const char* title) : GuiScreensaverOptions(window, title)
{
ComponentListRow row;
// image duration (seconds)
auto sss_image_sec = std::make_shared<SliderComponent>(mWindow, 1.f, 60.f, 1.f, "s");
sss_image_sec->setValue((float)(Settings::getInstance()->getInt("ScreenSaverSwapImageTimeout") / (1000)));
addWithLabel(row, "SWAP IMAGE AFTER (SECS)", sss_image_sec);
addSaveFunc([sss_image_sec] {
int playNextTimeout = (int)round(sss_image_sec->getValue()) * (1000);
Settings::getInstance()->setInt("ScreenSaverSwapImageTimeout", playNextTimeout);
PowerSaver::updateTimeouts();
});
// stretch
auto sss_stretch = std::make_shared<SwitchComponent>(mWindow);
sss_stretch->setState(Settings::getInstance()->getBool("SlideshowScreenSaverStretch"));
addWithLabel(row, "STRETCH IMAGES", sss_stretch);
addSaveFunc([sss_stretch] {
Settings::getInstance()->setBool("SlideshowScreenSaverStretch", sss_stretch->getState());
});
// background audio file
auto sss_bg_audio_file = std::make_shared<TextComponent>(mWindow, "", Font::get(FONT_SIZE_SMALL), 0x777777FF);
addEditableTextComponent(row, "BACKGROUND AUDIO", sss_bg_audio_file, Settings::getInstance()->getString("SlideshowScreenSaverBackgroundAudioFile"));
addSaveFunc([sss_bg_audio_file] {
Settings::getInstance()->setString("SlideshowScreenSaverBackgroundAudioFile", sss_bg_audio_file->getValue());
});
// image source
auto sss_custom_source = std::make_shared<SwitchComponent>(mWindow);
sss_custom_source->setState(Settings::getInstance()->getBool("SlideshowScreenSaverCustomImageSource"));
addWithLabel(row, "USE CUSTOM IMAGES", sss_custom_source);
addSaveFunc([sss_custom_source] { Settings::getInstance()->setBool("SlideshowScreenSaverCustomImageSource", sss_custom_source->getState()); });
// custom image directory
auto sss_image_dir = std::make_shared<TextComponent>(mWindow, "", Font::get(FONT_SIZE_SMALL), 0x777777FF);
addEditableTextComponent(row, "CUSTOM IMAGE DIR", sss_image_dir, Settings::getInstance()->getString("SlideshowScreenSaverImageDir"));
addSaveFunc([sss_image_dir] {
Settings::getInstance()->setString("SlideshowScreenSaverImageDir", sss_image_dir->getValue());
});
// recurse custom image directory
auto sss_recurse = std::make_shared<SwitchComponent>(mWindow);
sss_recurse->setState(Settings::getInstance()->getBool("SlideshowScreenSaverRecurse"));
addWithLabel(row, "CUSTOM IMAGE DIR RECURSIVE", sss_recurse);
addSaveFunc([sss_recurse] {
Settings::getInstance()->setBool("SlideshowScreenSaverRecurse", sss_recurse->getState());
});
// custom image filter
auto sss_image_filter = std::make_shared<TextComponent>(mWindow, "", Font::get(FONT_SIZE_SMALL), 0x777777FF);
addEditableTextComponent(row, "CUSTOM IMAGE FILTER", sss_image_filter, Settings::getInstance()->getString("SlideshowScreenSaverImageFilter"));
addSaveFunc([sss_image_filter] {
Settings::getInstance()->setString("SlideshowScreenSaverImageFilter", sss_image_filter->getValue());
});
}
GuiSlideshowScreensaverOptions::~GuiSlideshowScreensaverOptions()
{
}
void GuiSlideshowScreensaverOptions::addWithLabel(ComponentListRow row, const std::string label, std::shared_ptr<GuiComponent> component)
{
row.elements.clear();
auto lbl = std::make_shared<TextComponent>(mWindow, strToUpper(label), Font::get(FONT_SIZE_MEDIUM), 0x777777FF);
row.addElement(lbl, true); // label
row.addElement(component, false, true);
addRow(row);
}
void GuiSlideshowScreensaverOptions::addEditableTextComponent(ComponentListRow row, const std::string label, std::shared_ptr<GuiComponent> ed, std::string value)
{
row.elements.clear();
auto lbl = std::make_shared<TextComponent>(mWindow, strToUpper(label), Font::get(FONT_SIZE_MEDIUM), 0x777777FF);
row.addElement(lbl, true); // label
row.addElement(ed, true);
auto spacer = std::make_shared<GuiComponent>(mWindow);
spacer->setSize(Renderer::getScreenWidth() * 0.005f, 0);
row.addElement(spacer, false);
auto bracket = std::make_shared<ImageComponent>(mWindow);
bracket->setImage(":/arrow.svg");
bracket->setResize(Eigen::Vector2f(0, lbl->getFont()->getLetterHeight()));
row.addElement(bracket, false);
auto updateVal = [ed](const std::string& newVal) { ed->setValue(newVal); }; // ok callback (apply new value to ed)
row.makeAcceptInputHandler([this, label, ed, updateVal] {
mWindow->pushGui(new GuiTextEditPopup(mWindow, label, ed->getValue(), updateVal, false));
});
assert(ed);
addRow(row);
ed->setValue(value);
}

View file

@ -0,0 +1,18 @@
#ifndef _GUI_SLIDESHOW_SCREENSAVER_OPTIONS_H_
#define _GUI_SLIDESHOW_SCREENSAVER_OPTIONS_H_
#include "components/MenuComponent.h"
#include "GuiScreensaverOptions.h"
class GuiSlideshowScreensaverOptions : public GuiScreensaverOptions
{
public:
GuiSlideshowScreensaverOptions(Window* window, const char* title);
virtual ~GuiSlideshowScreensaverOptions();
private:
void addWithLabel(ComponentListRow row, const std::string label, std::shared_ptr<GuiComponent> component);
void addEditableTextComponent(ComponentListRow row, const std::string label, std::shared_ptr<GuiComponent> ed, std::string value);
};
#endif // _GUI_SLIDESHOW_SCREENSAVER_OPTIONS_H_

View file

@ -0,0 +1,82 @@
#include "guis/GuiVideoScreensaverOptions.h"
#include "Window.h"
#include "Settings.h"
#include "views/ViewController.h"
#include "components/SwitchComponent.h"
#include "components/SliderComponent.h"
#include "components/OptionListComponent.h"
#include "components/MenuComponent.h"
#include "guis/GuiMsgBox.h"
#include "PowerSaver.h"
GuiVideoScreensaverOptions::GuiVideoScreensaverOptions(Window* window, const char* title) : GuiScreensaverOptions(window, title)
{
// timeout to swap videos
auto swap = std::make_shared<SliderComponent>(mWindow, 10.f, 1000.f, 1.f, "s");
swap->setValue((float)(Settings::getInstance()->getInt("ScreenSaverSwapVideoTimeout") / (1000)));
addWithLabel("SWAP VIDEO AFTER (SECS)", swap);
addSaveFunc([swap] {
int playNextTimeout = (int)round(swap->getValue()) * (1000);
Settings::getInstance()->setInt("ScreenSaverSwapVideoTimeout", playNextTimeout);
PowerSaver::updateTimeouts();
});
#ifdef _RPI_
auto ss_omx = std::make_shared<SwitchComponent>(mWindow);
ss_omx->setState(Settings::getInstance()->getBool("ScreenSaverOmxPlayer"));
addWithLabel("USE OMX PLAYER FOR SCREENSAVER", ss_omx);
addSaveFunc([ss_omx, this] { Settings::getInstance()->setBool("ScreenSaverOmxPlayer", ss_omx->getState()); });
#endif
// Allow ScreenSaver Controls - ScreenSaverControls
auto ss_controls = std::make_shared<SwitchComponent>(mWindow);
ss_controls->setState(Settings::getInstance()->getBool("ScreenSaverControls"));
addWithLabel("SCREENSAVER CONTROLS", ss_controls);
addSaveFunc([ss_controls] { Settings::getInstance()->setBool("ScreenSaverControls", ss_controls->getState()); });
// Render Video Game Name as subtitles
auto ss_info = std::make_shared< OptionListComponent<std::string> >(mWindow, "SHOW GAME INFO", false);
std::vector<std::string> info_type;
info_type.push_back("always");
info_type.push_back("start & end");
info_type.push_back("never");
for(auto it = info_type.begin(); it != info_type.end(); it++)
ss_info->add(*it, *it, Settings::getInstance()->getString("ScreenSaverGameInfo") == *it);
addWithLabel("SHOW GAME INFO ON SCREENSAVER", ss_info);
addSaveFunc([ss_info, this] { Settings::getInstance()->setString("ScreenSaverGameInfo", ss_info->getSelected()); });
#ifndef _RPI_
auto captions_compatibility = std::make_shared<SwitchComponent>(mWindow);
captions_compatibility->setState(Settings::getInstance()->getBool("CaptionsCompatibility"));
addWithLabel("USE COMPATIBLE LOW RESOLUTION FOR CAPTIONS", captions_compatibility);
addSaveFunc([captions_compatibility] { Settings::getInstance()->setBool("CaptionsCompatibility", captions_compatibility->getState()); });
#endif
auto stretch_screensaver = std::make_shared<SwitchComponent>(mWindow);
stretch_screensaver->setState(Settings::getInstance()->getBool("StretchVideoOnScreenSaver"));
addWithLabel("STRETCH VIDEO ON SCREENSAVER", stretch_screensaver);
addSaveFunc([stretch_screensaver] { Settings::getInstance()->setBool("StretchVideoOnScreenSaver", stretch_screensaver->getState()); });
}
GuiVideoScreensaverOptions::~GuiVideoScreensaverOptions()
{
}
void GuiVideoScreensaverOptions::save()
{
#ifdef _RPI_
bool startingStatusNotRisky = (Settings::getInstance()->getString("ScreenSaverGameInfo") == "never" || !Settings::getInstance()->getBool("ScreenSaverOmxPlayer"));
#endif
GuiScreensaverOptions::save();
#ifdef _RPI_
bool endStatusRisky = (Settings::getInstance()->getString("ScreenSaverGameInfo") != "never" && Settings::getInstance()->getBool("ScreenSaverOmxPlayer"));
if (startingStatusNotRisky && endStatusRisky) {
// if before it wasn't risky but now there's a risk of problems, show warning
mWindow->pushGui(new GuiMsgBox(mWindow,
"Using OMX Player and displaying Game Info may result in the video flickering in some TV modes. If that happens, consider:\n\n• Disabling the \"Show Game Info\" option;\n• Disabling \"Overscan\" on the Pi configuration menu might help:\nRetroPie > Raspi-Config > Advanced Options > Overscan > \"No\".\n• Disabling the use of OMX Player for the screensaver.",
"GOT IT!", [] { return; }));
}
#endif
}

View file

@ -0,0 +1,16 @@
#ifndef _GUI_VIDEO_SCREENSAVER_OPTIONS_H_
#define _GUI_VIDEO_SCREENSAVER_OPTIONS_H_
#include "components/MenuComponent.h"
#include "GuiScreensaverOptions.h"
class GuiVideoScreensaverOptions : public GuiScreensaverOptions
{
public:
GuiVideoScreensaverOptions(Window* window, const char* title);
virtual ~GuiVideoScreensaverOptions();
void save() override;
};
#endif // _GUI_VIDEO_SCREENSAVER_OPTIONS_H_

View file

@ -27,6 +27,8 @@ void PowerSaver::loadWakeupTime()
std::string behaviour = Settings::getInstance()->getString("ScreenSaverBehavior"); std::string behaviour = Settings::getInstance()->getString("ScreenSaverBehavior");
if (behaviour == "random video") if (behaviour == "random video")
mWakeupTimeout = Settings::getInstance()->getInt("ScreenSaverSwapVideoTimeout") - getMode(); mWakeupTimeout = Settings::getInstance()->getInt("ScreenSaverSwapVideoTimeout") - getMode();
else if (behaviour == "slideshow")
mWakeupTimeout = Settings::getInstance()->getInt("ScreenSaverSwapImageTimeout") - getMode();
else // Dim and Blank else // Dim and Blank
mWakeupTimeout = -1; mWakeupTimeout = -1;
} }

View file

@ -88,6 +88,14 @@ void Settings::setDefaults()
mBoolMap["StretchVideoOnScreenSaver"] = false; mBoolMap["StretchVideoOnScreenSaver"] = false;
mStringMap["PowerSaverMode"] = "disabled"; mStringMap["PowerSaverMode"] = "disabled";
mIntMap["ScreenSaverSwapImageTimeout"] = 10000;
mBoolMap["SlideshowScreenSaverStretch"] = false;
mStringMap["SlideshowScreenSaverBackgroundAudioFile"] = getHomePath() + "/.emulationstation/slideshow/audio/slideshow_bg.wav";
mBoolMap["SlideshowScreenSaverCustomImageSource"] = false;
mStringMap["SlideshowScreenSaverImageDir"] = getHomePath() + "/.emulationstation/slideshow/image";
mStringMap["SlideshowScreenSaverImageFilter"] = ".png,.jpg";
mBoolMap["SlideshowScreenSaverRecurse"] = false;
// This setting only applies to raspberry pi but set it for all platforms so // This setting only applies to raspberry pi but set it for all platforms so
// we don't get a warning if we encounter it on a different platform // we don't get a warning if we encounter it on a different platform
mBoolMap["VideoOmxPlayer"] = false; mBoolMap["VideoOmxPlayer"] = false;