1 //===========================================
2 //  Lumina-DE source code
3 //  Copyright (c) 2015, Ken Moore
4 //  Available under the 3-clause BSD license
5 //  See the LICENSE file for full details
6 //===========================================
7 #ifndef _LUMINA_DESKTOP_SCREEN_SAVER_IMAGESLIDESHOW_ANIMATION_H
8 #define _LUMINA_DESKTOP_SCREEN_SAVER_IMAGESLIDESHOW_ANIMATION_H
9 
10 #include "global-includes.h"
11 #include "BaseAnimGroup.h"
12 
13 class ImageSlideshow: public QParallelAnimationGroup{
14 	Q_OBJECT
15 private:
16 	QLabel *image;
17 	QPropertyAnimation *bounce, *fading;
18 	QPixmap pixmap;
19 	QStringList imageFiles;
20 	QString imagePath, scriptPath, curpixmap;
21 	QSize screenSize;
22 	bool animate, scriptLoad;
23 
24 private:
setupAnimation()25 	void setupAnimation() {
26 	  //Choose between starting from top or bottom at random
27 	  if(qrand() % 2) {
28 		  bounce->setKeyValueAt(0, QPoint(0,screenSize.height()-image->height()));
29 		  bounce->setKeyValueAt(0.25, QPoint((screenSize.width()-image->width())/2,0));
30 		  bounce->setKeyValueAt(0.5, QPoint(screenSize.width()-image->width(),screenSize.height()-image->height()));
31 		  bounce->setKeyValueAt(0.75, QPoint((screenSize.width()-image->width())/2,0));
32 		  bounce->setKeyValueAt(1, QPoint(0,screenSize.height()-image->height()));
33 	  }else{
34 		  bounce->setKeyValueAt(0, QPoint(0,0));
35 		  bounce->setKeyValueAt(0.25, QPoint((screenSize.width()-image->width())/2,screenSize.height()-image->height()));
36 		  bounce->setKeyValueAt(0.5, QPoint(screenSize.width()-image->width(),0));
37 		  bounce->setKeyValueAt(0.75, QPoint((screenSize.width()-image->width())/2,screenSize.height()-image->height()));
38 		  bounce->setKeyValueAt(1, QPoint(0,0));
39 	  }
40 	}
41 
chooseImage()42 	void chooseImage() {
43 	  /*if(scriptLoad){
44 	    QProcess process;
45 	    process.start("/home/zwelch/test.sh");
46 	    process.waitForFinished(1000);
47 	    QByteArray output = process.readAllStandardOutput();
48 	    //qDebug() << output;
49 	    //pixmap.load(randomFile);
50 	  }else{*/
51 	    //File Load
52 	    QString randomFile = curpixmap;
53 	    if(imageFiles.size()>1 || curpixmap.isEmpty()){
54               while(curpixmap==randomFile){ randomFile = imagePath+imageFiles[qrand() % imageFiles.size()]; }
55 	    }
56             if(curpixmap!=randomFile){
57               curpixmap = randomFile; //save this for later
58 	      //no need to load the new file or change the label
59               pixmap.load(randomFile);
60 	      //If the image is larger than the screen, then shrink the image down to 3/4 it's size (so there's still some bounce)
61 		//Scale the pixmap to keep the aspect ratio instead of resizing the label itself
62 	      if(pixmap.width() >= (screenSize.width()-10) || pixmap.height() >= (screenSize.height()-10) ){
63 	        pixmap = pixmap.scaled(screenSize*(3.0/4.0), Qt::KeepAspectRatio);
64 	      }
65 	      //Set pixmap to the image label
66 	      image->setPixmap(pixmap);
67 	      image->resize(pixmap.size());
68 	    }
69 	//}
70 
71 	}
72 
73 private slots:
LoopChanged()74 	void LoopChanged(){
75 	  //Load a new random image. Resize the label based on the image's size
76 	  chooseImage();
77 	  setupAnimation();
78 	}
stopped()79 	void stopped(){ image->hide();}
80 
81 public:
ImageSlideshow(QWidget * parent,QString path,bool animate,bool scriptLoad,QString scriptPath)82 	ImageSlideshow(QWidget *parent, QString path, bool animate, bool scriptLoad, QString scriptPath) : QParallelAnimationGroup(parent){
83 	  imagePath = path;
84 	  image = new QLabel(parent);
85 	  screenSize = parent->size();
86 	  this->animate = animate;
87 	  this->scriptLoad = scriptLoad;
88 	  this->scriptPath = scriptPath;
89 
90 	  //Generate the list of files in the directory
91 	  imageFiles = QDir(imagePath).entryList(QDir::Files);
92 	  //Ensure all the files are actually images
93 	  for(int i=0; i<imageFiles.length(); i++){
94 	    if(QImageReader::imageFormat(imagePath+"/"+imageFiles[i]).isEmpty()){ imageFiles.removeAt(i); i--; }
95 	  }
96 	  if(imageFiles.empty()){
97 	    qDebug() << "Current image file path has no files.";
98 	    image->setText("No image files found:\n"+imagePath);
99 	  }else{
100 	    //Change some default settings for the image. If scaledContents is false, the image will be cut off if resized
101 	    image->setScaledContents(true);
102 	    image->setAlignment(Qt::AlignHCenter);
103 	    //Load a random initial image
104 	    chooseImage();
105 	  }
106 
107 	  //Create the animation that moves the image across the screen
108 	  bounce = new QPropertyAnimation(image, "pos", parent);
109 
110 	  //Add the animation that fades the image in and out
111 	  QGraphicsOpacityEffect *eff = new QGraphicsOpacityEffect(parent);
112 	  image->setGraphicsEffect(eff);
113 	  fading = new QPropertyAnimation(eff,"opacity");
114 	  fading->setKeyValueAt(0, 0);
115 	  fading->setKeyValueAt(0.20, 1);
116 	  fading->setKeyValueAt(0.80, 1);
117 	  fading->setKeyValueAt(1, 0);
118 	  this->addAnimation(fading);
119 
120 	  setupAnimation();
121 	  image->show();
122 	  //Only add the animation if set in the configuration file
123 	  if(animate)
124 		  this->addAnimation(bounce);
125 	  else
126 		  //If no animation, center the image in the middle of the screen
127 		  image->move(QPoint((parent->width()-image->width())/2,(parent->height()-image->height())/2));
128 
129 	  //Loop through 15 times for a total for 2 minutes
130 	  this->setLoopCount(15);
131 	  bounce->setDuration(8000);
132 	  fading->setDuration(8000);
133 
134 	  connect(this, SIGNAL(currentLoopChanged(int)), this, SLOT(LoopChanged()) );
135 	  connect(this, SIGNAL(finished()), this, SLOT(stopped()) );
136 	}
~ImageSlideshow()137 	~ImageSlideshow(){}
138 
139 };
140 
141 class ImageAnimation: public BaseAnimGroup{
142 	Q_OBJECT
143 public:
ImageAnimation(QWidget * parent)144 	ImageAnimation(QWidget *parent) : BaseAnimGroup(parent){}
~ImageAnimation()145 	~ImageAnimation(){
146 	  this->stop();
147 	}
148 
LoadAnimations()149 	void LoadAnimations(){
150 	  canvas->setStyleSheet("background: black;");
151 	  //Load the path of the images from the configuration file (default /usr/local/backgrounds/)
152 	  QString imagePath = readSetting("path", LOS::LuminaShare()+"../wallpapers/").toString();
153 	  //Load whether to animate the image (default true)
154 	  bool animate = readSetting("animate", true).toBool();
155 	  bool scriptLoad = readSetting("scriptLoad", true).toBool();
156 	  QString scriptPath;
157 	  if(scriptLoad){
158 	    scriptPath = readSetting("scriptPath", "/usr/local/backgrounds/script.sh").toString();
159 	  }
160 	  ImageSlideshow *tmp = new ImageSlideshow(canvas, imagePath, animate, scriptLoad, scriptPath);
161 	  this->addAnimation(tmp);
162 	}
163 
164 };
165 #endif
166