Merge branch 'master' of https://github.com/NautiluX/slide into NautiluX-master

This commit is contained in:
alfred-reynolds
2021-08-02 21:15:11 +12:00
5 changed files with 137 additions and 70 deletions

View File

@@ -47,6 +47,8 @@ slide [-t rotation_seconds] [-a aspect] [-o background_opacity(0..255)] [-b blur
* `<path>`path to the current image without filename * `<path>`path to the current image without filename
* Example: `slide -p ./images -O "20|60|Time: <time>;;;Picture taken at <exifdatetime>"` * Example: `slide -p ./images -O "20|60|Time: <time>;;;Picture taken at <exifdatetime>"`
To exit the application, press escape. If you're using a touch display, touch all 4 corners at the same time.
## Folder Options file ## Folder Options file
When using the default or recursive folder mode we support having per folder display options. The options are stored in a file called "options.json" and currently support the following option When using the default or recursive folder mode we support having per folder display options. The options are stored in a file called "options.json" and currently support the following option
``` ```

View File

@@ -19,7 +19,7 @@ ImageSelector::ImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char
ImageSelector::~ImageSelector(){} ImageSelector::~ImageSelector(){}
int ImageSelector::getImageRotation(const std::string &fileName) int ImageSelector::getImageRotation(const std::string& fileName)
{ {
int orientation = 0; int orientation = 0;
ExifData *exifData = exif_data_new_from_file(fileName.c_str()); ExifData *exifData = exif_data_new_from_file(fileName.c_str());
@@ -50,6 +50,28 @@ int ImageSelector::getImageRotation(const std::string &fileName)
return degrees; return degrees;
} }
bool ImageSelector::imageMatchesFilter(const std::string& fileName, int rotation)
{
if(!QFileInfo::exists(QString(fileName.c_str())))
{
if(debugMode)
{
std::cout << "file not found: " << fileName << std::endl;
}
return false;
}
if(!imageValidForAspect(fileName, rotation)) {
if(debugMode)
{
std::cout << "image aspect ratio doesn't match filter '" << aspect << "' : " << fileName << std::endl;
}
return false;
}
return true;
}
bool ImageSelector::imageValidForAspect(const std::string &fileName, const int rotation) bool ImageSelector::imageValidForAspect(const std::string &fileName, const int rotation)
{ {
QPixmap p( fileName.c_str() ); QPixmap p( fileName.c_str() );
@@ -95,18 +117,16 @@ const std::string RandomImageSelector::getNextImage(ImageOptions_t &options)
std:: string filename; std:: string filename;
try try
{ {
while (filename.empty()) QStringList images = pathTraverser->getImages();
unsigned int selectedImage = selectRandom(images);
filename = pathTraverser->getImagePath(images.at(selectedImage).toStdString());
options.rotation = getImageRotation(filename);
while(!imageMatchesFilter(filename, options.rotation))
{ {
QStringList images = pathTraverser->getImages();
unsigned int selectedImage = selectRandom(images); unsigned int selectedImage = selectRandom(images);
filename = pathTraverser->getImagePath(images.at(selectedImage).toStdString()); filename = pathTraverser->getImagePath(images.at(selectedImage).toStdString());
options.rotation = getImageRotation(filename); options.rotation = getImageRotation(filename);
if (!imageValidForAspect(filename, options.rotation))
{
filename.clear();
}
} }
} }
catch(const std::string& err) catch(const std::string& err)
{ {
@@ -145,6 +165,29 @@ ShuffleImageSelector::~ShuffleImageSelector()
} }
const std::string ShuffleImageSelector::getNextImage(ImageOptions_t &options) const std::string ShuffleImageSelector::getNextImage(ImageOptions_t &options)
{
reloadImagesIfNoneLeft();
if (images.size() == 0)
{
return "";
}
std::string filename = pathTraverser->getImagePath(images.at(current_image_shuffle).toStdString());
current_image_shuffle = current_image_shuffle + 1; // ignore and move to next image
options.rotation = getImageRotation(filename);
while(!imageMatchesFilter(filename, options.rotation)) {
reloadImagesIfNoneLeft();
std::string filename = pathTraverser->getImagePath(images.at(current_image_shuffle).toStdString());
options.rotation = getImageRotation(filename);
current_image_shuffle = current_image_shuffle + 1; // ignore and move to next image
}
std::cout << "updating image: " << filename << std::endl;
options.aspect = aspect;
options.fitAspectAxisToWindow = fitAspectAxisToWindow;
pathTraverser->UpdateOptionsForImage(filename, options);
return filename;
}
void ShuffleImageSelector::reloadImagesIfNoneLeft()
{ {
if (images.size() == 0 || current_image_shuffle >= images.size()) if (images.size() == 0 || current_image_shuffle >= images.size())
{ {
@@ -155,40 +198,10 @@ const std::string ShuffleImageSelector::getNextImage(ImageOptions_t &options)
std::mt19937 randomizer(rd()); std::mt19937 randomizer(rd());
std::shuffle(images.begin(), images.end(), randomizer); 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())))
{
if(debugMode)
{
std::cout << "file not found: " << filename << std::endl;
}
current_image_shuffle = current_image_shuffle + 1; // ignore and move to next image
return getNextImage(options);
}
options.rotation = getImageRotation(filename);
if (!imageValidForAspect(filename, options.rotation))
{
if(debugMode)
{
std::cout << "image has invalid aspect: " << filename << "(images left:" << (images.size()-current_image_shuffle) << ")" << std::endl;
}
current_image_shuffle = current_image_shuffle + 1; // ignore and move to next image
return getNextImage(options);
}
std::cout << "updating image: " << filename << std::endl;
current_image_shuffle = current_image_shuffle + 1;
options.aspect = aspect;
options.fitAspectAxisToWindow = fitAspectAxisToWindow;
pathTraverser->UpdateOptionsForImage(filename, options);
return filename;
} }
SortedImageSelector::SortedImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspect, bool fitAspectAxisToWindow): SortedImageSelector::SortedImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspect):
ImageSelector(pathTraverser, aspect, fitAspectAxisToWindow), ImageSelector(pathTraverser, aspect),
images() images()
{ {
srand (time(NULL)); srand (time(NULL));
@@ -212,40 +225,17 @@ bool operator<(const QString& lhs, const QString& rhs) noexcept{
const std::string SortedImageSelector::getNextImage(ImageOptions_t &options) const std::string SortedImageSelector::getNextImage(ImageOptions_t &options)
{ {
if (images.size() == 0) reloadImagesIfEmpty();
{
images = pathTraverser->getImages();
std::sort(images.begin(), images.end());
if(debugMode)
{
std::cout << "read " << images.size() << " images." << std::endl;
for (int i = 0;i <images.size();i++){
std::cout << images[i].toStdString() << std::endl;
}
}
}
if (images.size() == 0) if (images.size() == 0)
{ {
return ""; return "";
} }
std::string filename = pathTraverser->getImagePath(images.takeFirst().toStdString()); std::string filename = pathTraverser->getImagePath(images.takeFirst().toStdString());
if(!QFileInfo::exists(QString(filename.c_str())))
{
if(debugMode)
{
std::cout << "file not found: " << filename << std::endl;
}
return getNextImage(options);
}
options.rotation = getImageRotation(filename); options.rotation = getImageRotation(filename);
if (!imageValidForAspect(filename, options.rotation)) while(!imageMatchesFilter(filename, options.rotation)) {
{ reloadImagesIfEmpty();
if(debugMode) filename = pathTraverser->getImagePath(images.takeFirst().toStdString());
{ options.rotation = getImageRotation(filename);
std::cout << "image has invalid aspect: " << filename << std::endl;
}
return getNextImage(options);
} }
std::cout << "updating image: " << filename << std::endl; std::cout << "updating image: " << filename << std::endl;
@@ -254,3 +244,19 @@ const std::string SortedImageSelector::getNextImage(ImageOptions_t &options)
pathTraverser->UpdateOptionsForImage(filename, options); pathTraverser->UpdateOptionsForImage(filename, options);
return filename; return filename;
} }
void SortedImageSelector::reloadImagesIfEmpty()
{
if (images.size() == 0)
{
images = pathTraverser->getImages();
std::sort(images.begin(), images.end());
if(debugMode)
{
std::cout << "read " << images.size() << " images." << std::endl;
for (int i = 0;i <images.size();i++){
std::cout << images[i].toStdString() << std::endl;
}
}
}
}

View File

@@ -26,6 +26,7 @@ public:
protected: protected:
int getImageRotation(const std::string &fileName); int getImageRotation(const std::string &fileName);
bool imageValidForAspect(const std::string &fileName, const int rotation); bool imageValidForAspect(const std::string &fileName, const int rotation);
bool imageMatchesFilter(const std::string& fileName);
std::unique_ptr<PathTraverser>& pathTraverser; std::unique_ptr<PathTraverser>& pathTraverser;
char aspect; char aspect;
bool fitAspectAxisToWindow = false; bool fitAspectAxisToWindow = false;
@@ -51,6 +52,7 @@ public:
virtual const std::string getNextImage(ImageOptions_t &options); virtual const std::string getNextImage(ImageOptions_t &options);
private: private:
void reloadImagesIfNoneLeft();
int current_image_shuffle; int current_image_shuffle;
QStringList images; QStringList images;
}; };
@@ -63,6 +65,7 @@ public:
virtual const std::string getNextImage(ImageOptions_t &options); virtual const std::string getNextImage(ImageOptions_t &options);
private: private:
void reloadImagesIfEmpty();
QStringList images; QStringList images;
}; };
#endif // IMAGESELECTOR_H #endif // IMAGESELECTOR_H

View File

@@ -23,6 +23,8 @@ MainWindow::MainWindow(QWidget *parent) :
ui->setupUi(this); ui->setupUi(this);
setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
setAttribute(Qt::WA_AcceptTouchEvents);
QTimer::singleShot(5, this, SLOT(showFullScreen())); QTimer::singleShot(5, this, SLOT(showFullScreen()));
QApplication::setOverrideCursor(Qt::BlankCursor); QApplication::setOverrideCursor(Qt::BlankCursor);
QLabel *label = this->findChild<QLabel*>("image"); QLabel *label = this->findChild<QLabel*>("image");
@@ -47,6 +49,59 @@ void MainWindow::keyPressEvent(QKeyEvent* event)
QWidget::keyPressEvent(event); QWidget::keyPressEvent(event);
} }
bool isTouchEvent(const QEvent &event)
{
if(event.type() == QEvent::TouchBegin)
return true;
if(event.type() == QEvent::TouchUpdate)
return true;
return false;
}
bool isQuitCombination(const QTouchEvent &touchEvent)
{
bool topLeftTouched = false;
bool topRightTouched = false;
bool bottomLeftTouched = false;
bool bottomRightTouched = false;
for(const auto &touchPoint : touchEvent.touchPoints())
{
const qreal normalizedCornerSize = 0.1;
const qreal x = touchPoint.normalizedPos().x();
const qreal y = touchPoint.normalizedPos().y();
if(x < normalizedCornerSize)
{
if(y < normalizedCornerSize)
topLeftTouched = true;
else if(y > 1-normalizedCornerSize)
bottomLeftTouched = true;
}
else if(x > 1-normalizedCornerSize)
{
if(y < normalizedCornerSize)
topRightTouched = true;
else if(y > 1-normalizedCornerSize)
bottomRightTouched = true;
}
}
return topLeftTouched && topRightTouched
&& bottomLeftTouched && bottomRightTouched;
}
bool MainWindow::event(QEvent* event)
{
if(isTouchEvent(*event))
{
if(isQuitCombination(dynamic_cast<QTouchEvent&>(*event)))
QCoreApplication::quit();
}
else
{
return QMainWindow::event(event);
}
return true;
}
void MainWindow::resizeEvent(QResizeEvent* event) void MainWindow::resizeEvent(QResizeEvent* event)
{ {
QMainWindow::resizeEvent(event); QMainWindow::resizeEvent(event);

View File

@@ -18,8 +18,9 @@ class MainWindow : public QMainWindow
public: public:
explicit MainWindow(QWidget *parent = 0); explicit MainWindow(QWidget *parent = 0);
void keyPressEvent(QKeyEvent* event); void keyPressEvent(QKeyEvent* event) override;
void resizeEvent(QResizeEvent* event); bool event(QEvent* event) override;
void resizeEvent(QResizeEvent* event) override;
~MainWindow(); ~MainWindow();
void setImage(const std::string& path, const ImageOptions_t &options); void setImage(const std::string& path, const ImageOptions_t &options);
void setBlurRadius(unsigned int blurRadius); void setBlurRadius(unsigned int blurRadius);