Skip to content

Commit

Permalink
Merge pull request #12 from NautiluX/split_traverser_selector
Browse files Browse the repository at this point in the history
Enable shuffle mode
  • Loading branch information
NautiluX authored Feb 14, 2020
2 parents 0eb9596 + d399dfa commit bddcde4
Show file tree
Hide file tree
Showing 9 changed files with 286 additions and 90 deletions.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,16 @@ qmake ../src/slide.pro
make
sudo make install
```

### macOS

Prerequisite: brew

```
brew install qt5
brew install libexif
mkdir -p build
cd build
qmake ../src/slide.pro
make
```
114 changes: 71 additions & 43 deletions src/imageselector.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "imageselector.h"
#include "pathtraverser.h"
#include "mainwindow.h"
#include <QDirIterator>
#include <QTimer>
Expand All @@ -7,59 +8,86 @@
#include <iostream>
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
#include <algorithm> // std::shuffle
#include <random> // std::default_random_engine

ImageSelector::ImageSelector(std::string path, bool recursive):
path(path),
recursive(recursive)
ImageSelector::ImageSelector(std::unique_ptr<PathTraverser>& pathTraverser):
pathTraverser(pathTraverser)
{
srand (time(NULL));
}

std::string ImageSelector::getNextImage() const
ImageSelector::~ImageSelector(){}

RandomImageSelector::RandomImageSelector(std::unique_ptr<PathTraverser>& pathTraverser):
ImageSelector(pathTraverser)
{
srand (time(NULL));
}

RandomImageSelector::~RandomImageSelector(){}

std::string RandomImageSelector::getNextImage()
{
QDir directory(path.c_str());
std:: string filename;
try
{
if (recursive)
{
QStringList images = listImagesRecursive();
unsigned int selectedImage = selectRandom(images);
filename = images.at(selectedImage).toStdString();
}
else
{
QStringList images = directory.entryList(QStringList() << "*.jpg" << "*.JPG", QDir::Files);
unsigned int selectedImage = selectRandom(images);
filename = directory.filePath(images.at(selectedImage)).toStdString();
}
}
catch(const std::string& err)
{
std::cerr << "Error: " << err << std::endl;
}
std::cout << "updating image: " << filename << std::endl;
return filename;
std:: string filename;
try
{
QStringList images = pathTraverser->getImages();
unsigned int selectedImage = selectRandom(images);
filename = pathTraverser->getImagePath(images.at(selectedImage).toStdString());
}
catch(const std::string& err)
{
std::cerr << "Error: " << err << std::endl;
}
std::cout << "updating image: " << filename << std::endl;
return filename;
}

unsigned int ImageSelector::selectRandom(const QStringList& images) const
unsigned int RandomImageSelector::selectRandom(const QStringList& images) const
{
std::cout << "images: " << images.size() << std::endl;
if (images.size() == 0)
{
throw std::string("No jpg images found in folder " + path);
}
return rand() % images.size();
std::cout << "images: " << images.size() << std::endl;
if (images.size() == 0)
{
throw std::string("No jpg images found in given folder");
}
return rand() % images.size();
}

ShuffleImageSelector::ShuffleImageSelector(std::unique_ptr<PathTraverser>& pathTraverser):
ImageSelector(pathTraverser),
current_image_shuffle(-1),
images()
{
srand (time(NULL));
}

ShuffleImageSelector::~ShuffleImageSelector()
{
}

QStringList ImageSelector::listImagesRecursive() const
std::string ShuffleImageSelector::getNextImage()
{
QDirIterator it(QString(path.c_str()), QStringList() << "*.jpg" << "*.JPG", QDir::Files, QDirIterator::Subdirectories);
QStringList files;
while (it.hasNext())
{
files.append(it.next());
}
return files;
if (images.size() == 0 || current_image_shuffle >= images.size())
{
current_image_shuffle = 0;
images = pathTraverser->getImages();
std::cout << "Shuffling " << images.size() << " images." << std::endl;
std::random_device rd;
std::mt19937 randomizer(rd());
std::shuffle(images.begin(), images.end(), randomizer);
}
if (images.size() == 0)
{
return "";
}
std::string filename = pathTraverser->getImagePath(images.at(current_image_shuffle).toStdString());
if(!QFileInfo::exists(QString(filename.c_str())))
{
std::cout << "file not found: " << filename << std::endl;
current_image_shuffle = images.size();
return getNextImage();
}
std::cout << "updating image: " << filename << std::endl;
current_image_shuffle = current_image_shuffle + 1;
return filename;
}
34 changes: 29 additions & 5 deletions src/imageselector.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,44 @@
#define IMAGESELECTOR_H

#include <iostream>
#include <memory>
#include <QStringList>

class MainWindow;
class PathTraverser;

class ImageSelector
{
public:
ImageSelector(std::string path, bool recursive);
std::string getNextImage() const;
ImageSelector(std::unique_ptr<PathTraverser>& pathTraverser);
virtual ~ImageSelector();
virtual std::string getNextImage() = 0;

protected:
std::unique_ptr<PathTraverser>& pathTraverser;
};

class RandomImageSelector : public ImageSelector
{
public:
RandomImageSelector(std::unique_ptr<PathTraverser>& pathTraverser);
virtual ~RandomImageSelector();
virtual std::string getNextImage();

private:
QStringList listImagesRecursive() const;
unsigned int selectRandom(const QStringList& images) const;
std::string path;
bool recursive;
};

class ShuffleImageSelector : public ImageSelector
{
public:
ShuffleImageSelector(std::unique_ptr<PathTraverser>& pathTraverser);
virtual ~ShuffleImageSelector();
virtual std::string getNextImage();

private:
int current_image_shuffle;
QStringList images;
};

#endif // IMAGESELECTOR_H
6 changes: 3 additions & 3 deletions src/imageswitcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
#include <QDirIterator>
#include <QTimer>
#include <QApplication>
#include <QDir>
#include <iostream>
#include <memory>
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */

ImageSwitcher::ImageSwitcher(MainWindow& w, unsigned int timeout, const ImageSelector& selector):
ImageSwitcher::ImageSwitcher(MainWindow& w, unsigned int timeout, std::unique_ptr<ImageSelector>& selector):
QObject::QObject(),
window(w),
timeout(timeout),
Expand All @@ -20,7 +20,7 @@ ImageSwitcher::ImageSwitcher(MainWindow& w, unsigned int timeout, const ImageSel

void ImageSwitcher::updateImage()
{
std::string filename(selector.getNextImage());
std::string filename(selector->getNextImage());
if (filename == "")
{
window.warn("No image found.");
Expand Down
5 changes: 3 additions & 2 deletions src/imageswitcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,23 @@
#include <QObject>
#include <QTimer>
#include <iostream>
#include <memory>

class MainWindow;
class ImageSelector;
class ImageSwitcher : public QObject
{
Q_OBJECT
public:
ImageSwitcher(MainWindow& w, unsigned int timeout, const ImageSelector& selector);
ImageSwitcher(MainWindow& w, unsigned int timeout, std::unique_ptr<ImageSelector>& selector);
void start();

public slots:
void updateImage();
private:
MainWindow& window;
unsigned int timeout;
const ImageSelector& selector;
std::unique_ptr<ImageSelector>& selector;
QTimer timer;
};

Expand Down
102 changes: 65 additions & 37 deletions src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "mainwindow.h"
#include "imageselector.h"
#include "imageswitcher.h"
#include "pathtraverser.h"
#include <QApplication>
#include <iostream>
#include <sys/file.h>
Expand All @@ -9,53 +10,80 @@
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <memory>

void usage(std::string programName) {
std::cerr << "Usage: " << programName << " [-t rotation_seconds] [-o background_opacity(0..255)] [-b blur_radius] -p image_folder -r" << std::endl;
}

int main(int argc, char *argv[])
{
unsigned int rotationSeconds = 30;
std::string path = "";

QApplication a(argc, argv);

MainWindow w;
int opt;
bool recursive = false;
while ((opt = getopt(argc, argv, "b:p:t:o:r")) != -1) {
switch (opt) {
case 'p':
path = optarg;
break;
case 't':
rotationSeconds = atoi(optarg);
break;
case 'b':
w.setBlurRadius(atoi(optarg));
break;
case 'o':
w.setBackgroundOpacity(atoi(optarg));
break;
case 'r':
recursive = true;
break;
default: /* '?' */
usage(argv[0]);
return 1;
}
}
unsigned int rotationSeconds = 30;
std::string path = "";

QApplication a(argc, argv);

if (path.empty()) {
std::cout << "Error: Path expected." << std::endl;
MainWindow w;
int opt;
bool recursive = false;
bool shuffle = false;
while ((opt = getopt(argc, argv, "b:p:t:o:rs")) != -1) {
switch (opt) {
case 'p':
path = optarg;
break;
case 't':
rotationSeconds = atoi(optarg);
break;
case 'b':
w.setBlurRadius(atoi(optarg));
break;
case 'o':
w.setBackgroundOpacity(atoi(optarg));
break;
case 'r':
recursive = true;
break;
case 's':
shuffle = true;
std::cout << "Shuffle mode is on." << std::endl;
break;
default: /* '?' */
usage(argv[0]);
return 1;
}
w.show();
}

if (path.empty())
{
std::cout << "Error: Path expected." << std::endl;
usage(argv[0]);
return 1;
}

std::unique_ptr<PathTraverser> pathTraverser;
if (recursive)
{
pathTraverser = std::unique_ptr<PathTraverser>(new RecursivePathTraverser(path));
}
else
{
pathTraverser = std::unique_ptr<PathTraverser>(new DefaultPathTraverser(path));
}

std::unique_ptr<ImageSelector> selector;
if (shuffle)
{
selector = std::unique_ptr<ImageSelector>(new ShuffleImageSelector(pathTraverser));
}
else
{
selector = std::unique_ptr<ImageSelector>(new RandomImageSelector(pathTraverser));
}

w.show();

ImageSelector selector(path, recursive);
ImageSwitcher switcher(w, rotationSeconds * 1000, selector);
switcher.start();
return a.exec();
ImageSwitcher switcher(w, rotationSeconds * 1000, selector);
switcher.start();
return a.exec();
}
Loading

0 comments on commit bddcde4

Please sign in to comment.