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
* 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
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(){}
int ImageSelector::getImageRotation(const std::string &fileName)
int ImageSelector::getImageRotation(const std::string& fileName)
{
int orientation = 0;
ExifData *exifData = exif_data_new_from_file(fileName.c_str());
@@ -50,6 +50,28 @@ int ImageSelector::getImageRotation(const std::string &fileName)
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)
{
QPixmap p( fileName.c_str() );
@@ -95,18 +117,16 @@ const std::string RandomImageSelector::getNextImage(ImageOptions_t &options)
std:: string filename;
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);
filename = pathTraverser->getImagePath(images.at(selectedImage).toStdString());
options.rotation = getImageRotation(filename);
if (!imageValidForAspect(filename, options.rotation))
{
filename.clear();
}
}
}
catch(const std::string& err)
{
@@ -145,6 +165,29 @@ ShuffleImageSelector::~ShuffleImageSelector()
}
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())
{
@@ -155,40 +198,10 @@ const std::string ShuffleImageSelector::getNextImage(ImageOptions_t &options)
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())))
{
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):
ImageSelector(pathTraverser, aspect, fitAspectAxisToWindow),
SortedImageSelector::SortedImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspect):
ImageSelector(pathTraverser, aspect),
images()
{
srand (time(NULL));
@@ -212,40 +225,17 @@ bool operator<(const QString& lhs, const QString& rhs) noexcept{
const std::string SortedImageSelector::getNextImage(ImageOptions_t &options)
{
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;
}
}
}
reloadImagesIfEmpty();
if (images.size() == 0)
{
return "";
}
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);
if (!imageValidForAspect(filename, options.rotation))
{
if(debugMode)
{
std::cout << "image has invalid aspect: " << filename << std::endl;
}
return getNextImage(options);
while(!imageMatchesFilter(filename, options.rotation)) {
reloadImagesIfEmpty();
filename = pathTraverser->getImagePath(images.takeFirst().toStdString());
options.rotation = getImageRotation(filename);
}
std::cout << "updating image: " << filename << std::endl;
@@ -254,3 +244,19 @@ const std::string SortedImageSelector::getNextImage(ImageOptions_t &options)
pathTraverser->UpdateOptionsForImage(filename, options);
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:
int getImageRotation(const std::string &fileName);
bool imageValidForAspect(const std::string &fileName, const int rotation);
bool imageMatchesFilter(const std::string& fileName);
std::unique_ptr<PathTraverser>& pathTraverser;
char aspect;
bool fitAspectAxisToWindow = false;
@@ -51,6 +52,7 @@ public:
virtual const std::string getNextImage(ImageOptions_t &options);
private:
void reloadImagesIfNoneLeft();
int current_image_shuffle;
QStringList images;
};
@@ -63,6 +65,7 @@ public:
virtual const std::string getNextImage(ImageOptions_t &options);
private:
void reloadImagesIfEmpty();
QStringList images;
};
#endif // IMAGESELECTOR_H

View File

@@ -23,6 +23,8 @@ MainWindow::MainWindow(QWidget *parent) :
ui->setupUi(this);
setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
setAttribute(Qt::WA_AcceptTouchEvents);
QTimer::singleShot(5, this, SLOT(showFullScreen()));
QApplication::setOverrideCursor(Qt::BlankCursor);
QLabel *label = this->findChild<QLabel*>("image");
@@ -47,6 +49,59 @@ void MainWindow::keyPressEvent(QKeyEvent* 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)
{
QMainWindow::resizeEvent(event);

View File

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