- Change the object ownership semantics to take ownership of unique_ptr's rather than references
- Add helper functions for setting up config - Add support for dynamically updating more config options (path related ones in particular)
This commit is contained in:
@@ -12,8 +12,8 @@
|
|||||||
#include <algorithm> // std::shuffle
|
#include <algorithm> // std::shuffle
|
||||||
#include <random> // std::default_random_engine
|
#include <random> // std::default_random_engine
|
||||||
|
|
||||||
ImageSelector::ImageSelector(std::unique_ptr<PathTraverser>& pathTraverser):
|
ImageSelector::ImageSelector(std::unique_ptr<PathTraverser>& pathTraverserIn):
|
||||||
pathTraverser(pathTraverser)
|
pathTraverser(std::move(pathTraverserIn))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ protected:
|
|||||||
ImageDetails populateImageDetails(const std::string&filename, const ImageDisplayOptions &baseOptions);
|
ImageDetails populateImageDetails(const std::string&filename, const ImageDisplayOptions &baseOptions);
|
||||||
bool imageValidForAspect(const ImageDetails& imageDetails);
|
bool imageValidForAspect(const ImageDetails& imageDetails);
|
||||||
bool imageMatchesFilter(const ImageDetails& imageDetails);
|
bool imageMatchesFilter(const ImageDetails& imageDetails);
|
||||||
std::unique_ptr<PathTraverser>& pathTraverser;
|
std::unique_ptr<PathTraverser> pathTraverser;
|
||||||
bool debugMode = false;
|
bool debugMode = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -9,11 +9,11 @@
|
|||||||
#include <stdlib.h> /* srand, rand */
|
#include <stdlib.h> /* srand, rand */
|
||||||
#include <time.h> /* time */
|
#include <time.h> /* time */
|
||||||
|
|
||||||
ImageSwitcher::ImageSwitcher(MainWindow& w, unsigned int timeoutMsec, std::shared_ptr<ImageSelector>& selector):
|
ImageSwitcher::ImageSwitcher(MainWindow& w, unsigned int timeoutMsec, std::unique_ptr<ImageSelector>& selector):
|
||||||
QObject::QObject(),
|
QObject::QObject(),
|
||||||
window(w),
|
window(w),
|
||||||
timeout(timeoutMsec),
|
timeout(timeoutMsec),
|
||||||
selector(selector),
|
selector(std::move(selector)),
|
||||||
timer(this),
|
timer(this),
|
||||||
timerNoContent(this)
|
timerNoContent(this)
|
||||||
{
|
{
|
||||||
@@ -23,7 +23,7 @@ void ImageSwitcher::updateImage()
|
|||||||
{
|
{
|
||||||
if(reloadConfigIfNeeded)
|
if(reloadConfigIfNeeded)
|
||||||
{
|
{
|
||||||
reloadConfigIfNeeded();
|
reloadConfigIfNeeded(window, this, selector.get());
|
||||||
}
|
}
|
||||||
ImageDetails imageDetails = selector->getNextImage(window.getBaseOptions());
|
ImageDetails imageDetails = selector->getNextImage(window.getBaseOptions());
|
||||||
if (imageDetails.filename == "")
|
if (imageDetails.filename == "")
|
||||||
@@ -52,7 +52,7 @@ void ImageSwitcher::scheduleImageUpdate()
|
|||||||
QTimer::singleShot(100, this, SLOT(updateImage()));
|
QTimer::singleShot(100, this, SLOT(updateImage()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageSwitcher::setConfigFileReloader(std::function<void()> reloadConfigIfNeededIn)
|
void ImageSwitcher::setConfigFileReloader(std::function<void(MainWindow &w, ImageSwitcher *switcher, ImageSelector *selector)> reloadConfigIfNeededIn)
|
||||||
{
|
{
|
||||||
reloadConfigIfNeeded = reloadConfigIfNeededIn;
|
reloadConfigIfNeeded = reloadConfigIfNeededIn;
|
||||||
}
|
}
|
||||||
@@ -62,3 +62,8 @@ void ImageSwitcher::setRotationTime(unsigned int timeoutMsecIn)
|
|||||||
timeout = timeoutMsecIn;
|
timeout = timeoutMsecIn;
|
||||||
timer.start(timeout);
|
timer.start(timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImageSwitcher::setImageSelector(std::unique_ptr<ImageSelector>& selectorIn)
|
||||||
|
{
|
||||||
|
selector = std::move(selectorIn);
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,29 +6,30 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include "imageselector.h"
|
||||||
|
|
||||||
class MainWindow;
|
class MainWindow;
|
||||||
class ImageSelector;
|
|
||||||
class ImageSwitcher : public QObject
|
class ImageSwitcher : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
ImageSwitcher(MainWindow& w, unsigned int timeoutMsec, std::shared_ptr<ImageSelector>& selector);
|
ImageSwitcher(MainWindow& w, unsigned int timeoutMsec, std::unique_ptr<ImageSelector>& selector);
|
||||||
void start();
|
void start();
|
||||||
void scheduleImageUpdate();
|
void scheduleImageUpdate();
|
||||||
void setConfigFileReloader(std::function<void()> reloadConfigIfNeededIn);
|
void setConfigFileReloader(std::function<void(MainWindow &w, ImageSwitcher *switcher, ImageSelector *selector)> reloadConfigIfNeededIn);
|
||||||
void setRotationTime(unsigned int timeoutMsec);
|
void setRotationTime(unsigned int timeoutMsec);
|
||||||
|
void setImageSelector(std::unique_ptr<ImageSelector>& selector);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void updateImage();
|
void updateImage();
|
||||||
private:
|
private:
|
||||||
MainWindow& window;
|
MainWindow& window;
|
||||||
unsigned int timeout;
|
unsigned int timeout;
|
||||||
std::shared_ptr<ImageSelector>& selector;
|
std::unique_ptr<ImageSelector> selector;
|
||||||
QTimer timer;
|
QTimer timer;
|
||||||
const unsigned int timeoutNoContent = 5 * 1000; // 5 sec
|
const unsigned int timeoutNoContent = 5 * 1000; // 5 sec
|
||||||
QTimer timerNoContent;
|
QTimer timerNoContent;
|
||||||
std::function<void()> reloadConfigIfNeeded;
|
std::function<void(MainWindow &w, ImageSwitcher *switcher, ImageSelector *selector)> reloadConfigIfNeeded;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // IMAGESWITCHER_H
|
#endif // IMAGESWITCHER_H
|
||||||
|
|||||||
136
src/main.cpp
136
src/main.cpp
@@ -24,6 +24,7 @@ void usage(std::string programName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Config {
|
struct Config {
|
||||||
|
public:
|
||||||
std::string path = "";
|
std::string path = "";
|
||||||
std::string configPath = "";
|
std::string configPath = "";
|
||||||
unsigned int rotationSeconds = 30;
|
unsigned int rotationSeconds = 30;
|
||||||
@@ -34,12 +35,23 @@ struct Config {
|
|||||||
bool sorted = false;
|
bool sorted = false;
|
||||||
bool debugMode = false;
|
bool debugMode = false;
|
||||||
ImageDisplayOptions baseDisplayOptions;
|
ImageDisplayOptions baseDisplayOptions;
|
||||||
std::string valid_aspects = "alpm"; // all, landscape, portait
|
static const std::string valid_aspects;
|
||||||
std::string overlay = "";
|
std::string overlay = "";
|
||||||
std::string imageList = ""; // comma delimited list of images to show
|
std::string imageList = ""; // comma delimited list of images to show
|
||||||
QDateTime loadTime;
|
QDateTime loadTime;
|
||||||
|
public:
|
||||||
|
bool PathOptionsChanged(Config &other) {
|
||||||
|
if ( other.recursive != recursive || other.shuffle != shuffle
|
||||||
|
|| other.sorted != sorted)
|
||||||
|
return true;
|
||||||
|
if ( other.path != path || other.imageList != imageList )
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const std::string Config::valid_aspects = "alpm"; // all, landscape, portait, monitor
|
||||||
|
|
||||||
ImageAspect parseAspectFromString(char aspect) {
|
ImageAspect parseAspectFromString(char aspect) {
|
||||||
switch(aspect)
|
switch(aspect)
|
||||||
{
|
{
|
||||||
@@ -243,7 +255,58 @@ bool parseCommandLine(Config &appConfig, int argc, char *argv[]) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReloadConfigIfNeeded(Config &appConfig, MainWindow &w, ImageSwitcher &switcher, std::shared_ptr<ImageSelector> &selector)
|
void ConfigureWindowFromSettings(MainWindow &w, const Config &appConfig)
|
||||||
|
{
|
||||||
|
if (appConfig.blurRadius>= 0)
|
||||||
|
{
|
||||||
|
w.setBlurRadius(appConfig.blurRadius);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (appConfig.backgroundOpacity>= 0)
|
||||||
|
{
|
||||||
|
w.setBackgroundOpacity(appConfig.backgroundOpacity);
|
||||||
|
}
|
||||||
|
std::unique_ptr<Overlay> o = std::unique_ptr<Overlay>(new Overlay(appConfig.overlay));
|
||||||
|
o->setDebugMode(appConfig.debugMode);
|
||||||
|
w.setDebugMode(appConfig.debugMode);
|
||||||
|
w.setOverlay(o);
|
||||||
|
w.setBaseOptions(appConfig.baseDisplayOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<ImageSelector> GetSelectorForConfig(const Config &appConfig)
|
||||||
|
{
|
||||||
|
std::unique_ptr<PathTraverser> pathTraverser;
|
||||||
|
if (!appConfig.imageList.empty())
|
||||||
|
{
|
||||||
|
pathTraverser = std::unique_ptr<PathTraverser>(new ImageListPathTraverser(appConfig.imageList, appConfig.debugMode));
|
||||||
|
}
|
||||||
|
else if (appConfig.recursive)
|
||||||
|
{
|
||||||
|
pathTraverser = std::unique_ptr<PathTraverser>(new RecursivePathTraverser(appConfig.path, appConfig.debugMode));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pathTraverser = std::unique_ptr<PathTraverser>(new DefaultPathTraverser(appConfig.path, appConfig.debugMode));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<ImageSelector> selector;
|
||||||
|
if (appConfig.sorted)
|
||||||
|
{
|
||||||
|
selector = std::unique_ptr<ImageSelector>(new SortedImageSelector(pathTraverser));
|
||||||
|
}
|
||||||
|
else if (appConfig.shuffle)
|
||||||
|
{
|
||||||
|
selector = std::unique_ptr<ImageSelector>(new ShuffleImageSelector(pathTraverser));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
selector = std::unique_ptr<ImageSelector>(new RandomImageSelector(pathTraverser));
|
||||||
|
}
|
||||||
|
|
||||||
|
return selector;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReloadConfigIfNeeded(Config &appConfig, MainWindow &w, ImageSwitcher *switcher, ImageSelector *selector)
|
||||||
{
|
{
|
||||||
QString jsonFile = getConfigFilePath(appConfig.configPath);
|
QString jsonFile = getConfigFilePath(appConfig.configPath);
|
||||||
QDir directory;
|
QDir directory;
|
||||||
@@ -254,13 +317,21 @@ void ReloadConfigIfNeeded(Config &appConfig, MainWindow &w, ImageSwitcher &switc
|
|||||||
|
|
||||||
if(appConfig.loadTime < QFileInfo(jsonFile).lastModified())
|
if(appConfig.loadTime < QFileInfo(jsonFile).lastModified())
|
||||||
{
|
{
|
||||||
|
const std::string oldPath = appConfig.path;
|
||||||
|
const std::string oldImageList = appConfig.imageList;
|
||||||
|
|
||||||
|
Config oldConfig = appConfig;
|
||||||
appConfig = loadConfiguration(appConfig);
|
appConfig = loadConfiguration(appConfig);
|
||||||
w.setBaseOptions(appConfig.baseDisplayOptions);
|
|
||||||
w.setDebugMode(appConfig.debugMode);
|
ConfigureWindowFromSettings(w, appConfig);
|
||||||
|
if(appConfig.PathOptionsChanged(oldConfig))
|
||||||
|
{
|
||||||
|
std::unique_ptr<ImageSelector> selector = GetSelectorForConfig(appConfig);
|
||||||
|
switcher->setImageSelector(selector);
|
||||||
|
}
|
||||||
|
|
||||||
selector->setDebugMode(appConfig.debugMode);
|
selector->setDebugMode(appConfig.debugMode);
|
||||||
//Overlay o(appConfig.overlay);
|
switcher->setRotationTime(appConfig.rotationSeconds * 1000);
|
||||||
//w.setOverlay(&o);
|
|
||||||
switcher.setRotationTime(appConfig.rotationSeconds * 1000);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,7 +339,6 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
|
|
||||||
MainWindow w;
|
|
||||||
Config commandLineAppConfig;
|
Config commandLineAppConfig;
|
||||||
if (!parseCommandLine(commandLineAppConfig, argc, argv))
|
if (!parseCommandLine(commandLineAppConfig, argc, argv))
|
||||||
{
|
{
|
||||||
@@ -285,58 +355,22 @@ int main(int argc, char *argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appConfig.blurRadius>= 0)
|
|
||||||
{
|
|
||||||
w.setBlurRadius(appConfig.blurRadius);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (appConfig.backgroundOpacity>= 0)
|
|
||||||
{
|
|
||||||
w.setBackgroundOpacity(appConfig.backgroundOpacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<PathTraverser> pathTraverser;
|
|
||||||
if (!appConfig.imageList.empty())
|
|
||||||
{
|
|
||||||
pathTraverser = std::unique_ptr<PathTraverser>(new ImageListPathTraverser(appConfig.imageList, appConfig.debugMode));
|
|
||||||
}
|
|
||||||
else if (appConfig.recursive)
|
|
||||||
{
|
|
||||||
pathTraverser = std::unique_ptr<PathTraverser>(new RecursivePathTraverser(appConfig.path, appConfig.debugMode));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pathTraverser = std::unique_ptr<PathTraverser>(new DefaultPathTraverser(appConfig.path, appConfig.debugMode));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<ImageSelector> selector;
|
|
||||||
if (appConfig.sorted)
|
|
||||||
{
|
|
||||||
selector = std::shared_ptr<ImageSelector>(new SortedImageSelector(pathTraverser));
|
|
||||||
}
|
|
||||||
else if (appConfig.shuffle)
|
|
||||||
{
|
|
||||||
selector = std::shared_ptr<ImageSelector>(new ShuffleImageSelector(pathTraverser));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
selector = std::shared_ptr<ImageSelector>(new RandomImageSelector(pathTraverser));
|
|
||||||
}
|
|
||||||
selector->setDebugMode(appConfig.debugMode);
|
|
||||||
if(appConfig.debugMode)
|
if(appConfig.debugMode)
|
||||||
{
|
{
|
||||||
std::cout << "Rotation Time: " << appConfig.rotationSeconds << std::endl;
|
std::cout << "Rotation Time: " << appConfig.rotationSeconds << std::endl;
|
||||||
std::cout << "Overlay input: " << appConfig.overlay << std::endl;
|
std::cout << "Overlay input: " << appConfig.overlay << std::endl;
|
||||||
}
|
}
|
||||||
Overlay o(appConfig.overlay);
|
|
||||||
o.setDebugMode(appConfig.debugMode);
|
MainWindow w;
|
||||||
w.setOverlay(&o);
|
ConfigureWindowFromSettings(w, appConfig);
|
||||||
w.setBaseOptions(appConfig.baseDisplayOptions);
|
|
||||||
w.show();
|
w.show();
|
||||||
|
|
||||||
|
std::unique_ptr<ImageSelector> selector = GetSelectorForConfig(appConfig);
|
||||||
|
selector->setDebugMode(appConfig.debugMode);
|
||||||
|
|
||||||
ImageSwitcher switcher(w, appConfig.rotationSeconds * 1000, selector);
|
ImageSwitcher switcher(w, appConfig.rotationSeconds * 1000, selector);
|
||||||
w.setImageSwitcher(&switcher);
|
w.setImageSwitcher(&switcher);
|
||||||
std::function<void()> reloader = [&appConfig, &w, &switcher, &selector]() { ReloadConfigIfNeeded(appConfig, w, switcher, selector); };
|
std::function<void(MainWindow &w, ImageSwitcher *switcher, ImageSelector *selector)> reloader = [&appConfig](MainWindow &w, ImageSwitcher *switcher, ImageSelector *selector) { ReloadConfigIfNeeded(appConfig, w, switcher, selector); };
|
||||||
switcher.setConfigFileReloader(reloader);
|
switcher.setConfigFileReloader(reloader);
|
||||||
switcher.start();
|
switcher.start();
|
||||||
return a.exec();
|
return a.exec();
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ void MainWindow::updateImage(bool immediately)
|
|||||||
QPixmap background = getBlurredBackground(rotated, scaled);
|
QPixmap background = getBlurredBackground(rotated, scaled);
|
||||||
drawForeground(background, scaled);
|
drawForeground(background, scaled);
|
||||||
|
|
||||||
if (overlay != NULL)
|
if (overlay != nullptr)
|
||||||
{
|
{
|
||||||
drawText(background, overlay->getMarginTopLeft(), overlay->getFontsizeTopLeft(), overlay->getRenderedTopLeft(currentImage.filename).c_str(), Qt::AlignTop|Qt::AlignLeft);
|
drawText(background, overlay->getMarginTopLeft(), overlay->getFontsizeTopLeft(), overlay->getRenderedTopLeft(currentImage.filename).c_str(), Qt::AlignTop|Qt::AlignLeft);
|
||||||
drawText(background, overlay->getMarginTopRight(), overlay->getFontsizeTopRight(), overlay->getRenderedTopRight(currentImage.filename).c_str(), Qt::AlignTop|Qt::AlignRight);
|
drawText(background, overlay->getMarginTopRight(), overlay->getFontsizeTopRight(), overlay->getRenderedTopRight(currentImage.filename).c_str(), Qt::AlignTop|Qt::AlignRight);
|
||||||
@@ -254,9 +254,9 @@ void MainWindow::drawForeground(QPixmap& background, const QPixmap& foreground)
|
|||||||
pt.drawPixmap((background.width()-foreground.width())/2, (background.height()-foreground.height())/2, foreground);
|
pt.drawPixmap((background.width()-foreground.width())/2, (background.height()-foreground.height())/2, foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setOverlay(Overlay* o)
|
void MainWindow::setOverlay(std::unique_ptr<Overlay> &o)
|
||||||
{
|
{
|
||||||
overlay = o;
|
overlay = std::move(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
QPixmap MainWindow::getBlurredBackground(const QPixmap& originalSize, const QPixmap& scaled)
|
QPixmap MainWindow::getBlurredBackground(const QPixmap& originalSize, const QPixmap& scaled)
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ public:
|
|||||||
void setBlurRadius(unsigned int blurRadius);
|
void setBlurRadius(unsigned int blurRadius);
|
||||||
void setBackgroundOpacity(unsigned int opacity);
|
void setBackgroundOpacity(unsigned int opacity);
|
||||||
void warn(std::string text);
|
void warn(std::string text);
|
||||||
void setOverlay(Overlay* overlay);
|
void setOverlay(std::unique_ptr<Overlay> &overlay);
|
||||||
void setDebugMode(bool debugModeIn);
|
void setDebugMode(bool debugModeIn);
|
||||||
void setBaseOptions(const ImageDisplayOptions &baseOptionsIn);
|
void setBaseOptions(const ImageDisplayOptions &baseOptionsIn);
|
||||||
const ImageDisplayOptions &getBaseOptions();
|
const ImageDisplayOptions &getBaseOptions();
|
||||||
@@ -46,7 +46,7 @@ private:
|
|||||||
bool debugMode = false;
|
bool debugMode = false;
|
||||||
QSize lastScreenSize = {0,0};
|
QSize lastScreenSize = {0,0};
|
||||||
|
|
||||||
Overlay* overlay = nullptr;
|
std::unique_ptr<Overlay> overlay;
|
||||||
ImageSwitcher *switcher = nullptr;
|
ImageSwitcher *switcher = nullptr;
|
||||||
|
|
||||||
void drawText(QPixmap& image, int margin, int fontsize, QString text, int alignment);
|
void drawText(QPixmap& image, int margin, int fontsize, QString text, int alignment);
|
||||||
|
|||||||
Reference in New Issue
Block a user