diff options
Diffstat (limited to 'src-qt5/core/lumina-desktop/src-screensaver/animations')
9 files changed, 813 insertions, 0 deletions
diff --git a/src-qt5/core/lumina-desktop/src-screensaver/animations/BaseAnimGroup.cpp b/src-qt5/core/lumina-desktop/src-screensaver/animations/BaseAnimGroup.cpp new file mode 100644 index 00000000..9b095fe4 --- /dev/null +++ b/src-qt5/core/lumina-desktop/src-screensaver/animations/BaseAnimGroup.cpp @@ -0,0 +1,51 @@ +//=========================================== +// Lumina-DE source code +// Copyright (c) 2015-2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "BaseAnimGroup.h" + +//Include all the known subclasses here, then add a unique ID for it to the functions at the bottom +//#include "SampleAnimation.h" +#include "Fireflies.h" +#include "Grav.h" +#include "SampleAnimation.h" +#include "Text.h" +#include "ImageSlideshow.h" +#include "VideoSlideshow.h" + + +QVariant BaseAnimGroup::readSetting(QString variable, QVariant defaultvalue){ + return DesktopSettings::instance()->value(DesktopSettings::ScreenSaver, + "Animations/"+animPlugin+"/"+variable, defaultvalue); +} + +//============================== +// PLUGIN LOADING/LISTING +//============================== +BaseAnimGroup* BaseAnimGroup::NewAnimation(QString type, QWidget *parent){ + //This is where we place all the known plugin ID's, and load the associated subclass + BaseAnimGroup *anim = 0; + if(type=="fireflies"){ + anim = new FirefliesAnimation(parent); + }else if(type == "grav") { + anim = new GravAnimation(parent); + }else if(type == "text") { + anim = new TextAnimation(parent); + }else if(type == "imageSlideshow") { + anim = new ImageAnimation(parent); + }else if(type == "videoSlideshow") { + anim = new VideoAnimation(parent); + }else { + //Unknown screensaver, return a blank animation group + anim = new BaseAnimGroup(parent); + } + //tag the animation with the type it is and return it + if(anim!=0){ anim->animPlugin = type; } + return anim; +} + +QStringList BaseAnimGroup::KnownAnimations(){ + return (QStringList() << "none" << "grav" << "text" << "imageSlideshow" << "videoSlideshow" << "fireflies"); +} diff --git a/src-qt5/core/lumina-desktop/src-screensaver/animations/BaseAnimGroup.h b/src-qt5/core/lumina-desktop/src-screensaver/animations/BaseAnimGroup.h new file mode 100644 index 00000000..92e038ed --- /dev/null +++ b/src-qt5/core/lumina-desktop/src-screensaver/animations/BaseAnimGroup.h @@ -0,0 +1,40 @@ +//=========================================== +// Lumina-DE source code +// Copyright (c) 2015-2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +// This class is the container which provides the screensaver animations +// and should be subclassed for each of the various animation types +//=========================================== +#ifndef _LUMINA_DESKTOP_SCREEN_SAVER_BASE_ANIMATION_GROUP_H +#define _LUMINA_DESKTOP_SCREEN_SAVER_BASE_ANIMATION_GROUP_H + +#include "global-includes.h" + +class BaseAnimGroup : public QParallelAnimationGroup{ + Q_OBJECT +public: + QWidget *canvas; + QString animPlugin; + + virtual void LoadAnimations(){} //This is the main function which needs to be subclassed + + BaseAnimGroup(QWidget *parent){ + canvas = parent; + canvas->setCursor( QCursor(Qt::BlankCursor) ); + } + ~BaseAnimGroup(){} + + QVariant readSetting(QString variable, QVariant defaultvalue = QVariant()); + + + //============================== + // PLUGIN LOADING/LISTING (Change in the .cpp file) + //============================== + static BaseAnimGroup* NewAnimation(QString type, QWidget *parent); + static QStringList KnownAnimations(); + +}; + +#endif diff --git a/src-qt5/core/lumina-desktop/src-screensaver/animations/Fireflies.h b/src-qt5/core/lumina-desktop/src-screensaver/animations/Fireflies.h new file mode 100644 index 00000000..dfc12e79 --- /dev/null +++ b/src-qt5/core/lumina-desktop/src-screensaver/animations/Fireflies.h @@ -0,0 +1,122 @@ +//=========================================== +// Lumina-DE source code +// Copyright (c) 2015, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +// This class is the sample plugin for a ScreenSaver animation +//=========================================== +#ifndef _LUMINA_DESKTOP_SCREEN_SAVER_FIREFLIES_ANIMATION_H +#define _LUMINA_DESKTOP_SCREEN_SAVER_FIREFLIES_ANIMATION_H + +#include "global-includes.h" +#include "BaseAnimGroup.h" +#include <QSequentialAnimationGroup> +#include <QGraphicsOpacityEffect> + +class Firefly : public QSequentialAnimationGroup{ + Q_OBJECT +private: + QWidget *fly; + QPropertyAnimation *movement, *flash; + int maxX, maxY; //maximum jitter in X/Y directions + QSize range; +private slots: + void LoopChanged(){ + //Adjust the movement animation a bit + movement->setStartValue(movement->endValue()); //start at the previous end point + QPoint pt = movement->startValue().toPoint(); + QPoint diff( (qrand()% maxX) - (maxX/2), (qrand()% maxY) - (maxY/2) ); + //Need to ensure it stays in the current box + if( (pt.x()+diff.x()) < 0 || (pt.x()+diff.x())>range.width()){ pt.setX(pt.x() - diff.x()); } //reverse the direction - otherwise will go out of bounds + else{ pt.setX( pt.x() + diff.x() ); } + if( (pt.y()+diff.y()) < 0 || (pt.y()+diff.y())>range.height()){ pt.setY(pt.y() - diff.y()); } //reverse the direction - otherwise will go out of bounds + else{ pt.setY( pt.y() + diff.y() ); } + movement->setEndValue(pt); + movement->setDuration( qrand() %500 + 1000); //between 1000->1500 ms animations for movements + //Adjust the flash duration/size a bit + flash->setDuration(qrand() %200 + 500); //500-700 ms + int sz = qrand()%4 + 4; //6-10 pixel square + //flash->setKeyValueAt(0.5, (qrand()%50) /100.0); + //fly->resize(sz,sz); + flash->setKeyValueAt(0.5, QSize(sz,sz)); //half-way point for the flash + + fly->show(); + } + void stopped(){ fly->hide(); } + +public: + Firefly(QWidget *parent) : QSequentialAnimationGroup(parent){ + fly = new QWidget(parent); + range = parent->size(); + maxX = range.width()/4; maxY = range.height()/4; + QString B = QString::number(qrand()%70); + QString RY = QString::number(qrand()%200+50); + QString style = "background-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(245, 245, 143, 200), stop:0.83871 rgba(%1, %1, %2, 140), stop:0.99 rgba(0, 0, 0, 255), stop:1 transparent);"; + fly->setStyleSheet(style.arg(RY, B) ); + //setup the movement animation + movement = new QPropertyAnimation(fly); + movement->setTargetObject(fly); + movement->setPropertyName("pos"); + movement->setEndValue( QPoint( qrand() % range.width(), qrand()%range.height()) ); //on anim start, this will become the starting point + //setup the flashing animation + /*QGraphicsOpacityEffect *eff = new QGraphicsOpacityEffect(parent); + fly->setGraphicsEffect(eff); + flash = new QPropertyAnimation(eff, "opacity");*/ + flash = new QPropertyAnimation(this); + flash->setTargetObject(fly); + flash->setPropertyName("size"); + flash->setStartValue(QSize(0,0)); + flash->setEndValue(flash->startValue()); + //fly->setProperty("opacity",0); + //flash->setPropertyName("opacity"); + //flash->setStartValue(0); + //flash->setEndValue(0); + //now setup the order of the animations + this->setLoopCount(100); //do this 100 times + //Roughly half the number of fireflies with start with movement/flash + if(qrand()%2 == 1){ + this->addAnimation(movement); + this->addAnimation(flash); + }else{ + this->addAnimation(flash); + this->addAnimation(movement); + } + //Start up this firefly + LoopChanged(); //load initial values + + fly->setGeometry( QRect(movement->startValue().toPoint(), flash->startValue().toSize()) ); + connect(this, SIGNAL(currentLoopChanged(int)), this, SLOT(LoopChanged()) ); + connect(this, SIGNAL(finished()), this, SLOT(stopped()) ); + } + ~Firefly(){} + +}; + +class FirefliesAnimation : public BaseAnimGroup{ + Q_OBJECT +private: + QList<Firefly*> fireflies; + +public: + FirefliesAnimation(QWidget *parent) : BaseAnimGroup(parent){} + ~FirefliesAnimation(){ + this->stop(); + //while(fireflies.length()>0){ fireflies.takeAt(0)->deleteLater(); } + } + + void LoadAnimations(){ + while(fireflies.length()>0){ fireflies.takeAt(0)->deleteLater(); } + canvas->setStyleSheet("background: black;"); + int number = readSetting("number",qrand()%30 + 50).toInt(); + for(int i=0; i<number; i++){ + if(fireflies.length()>number){ continue; } + Firefly *tmp = new Firefly(canvas); + this->addAnimation(tmp); + fireflies << tmp; + } + + } + +}; +#endif diff --git a/src-qt5/core/lumina-desktop/src-screensaver/animations/Grav.h b/src-qt5/core/lumina-desktop/src-screensaver/animations/Grav.h new file mode 100644 index 00000000..df75ad67 --- /dev/null +++ b/src-qt5/core/lumina-desktop/src-screensaver/animations/Grav.h @@ -0,0 +1,195 @@ +//=========================================== +// Lumina-DE source code +// Copyright (c) 2015, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#ifndef _LUMINA_DESKTOP_SCREEN_SAVER_GRAV_ANIMATION_H +#define _LUMINA_DESKTOP_SCREEN_SAVER_GRAV_ANIMATION_H + +//PI is equal to 2*pi +#define PI 6.2832 +#include "global-includes.h" +#include "BaseAnimGroup.h" +#include <QtMath> +#include <QMatrix> + +class Grav: public QParallelAnimationGroup{ + Q_OBJECT +private: + QWidget *planet; + QPropertyAnimation *orbit; + QSize range; + //QList<QPoint> path; + double radius; + + void setupLoop(QPoint start, QPoint *ref){ + //orbit->setStartValue(start); + + //Used to find overall speed. Distance from the planet to the sun + radius = qSqrt( (qPow(start.x()-ref->x(),2) + qPow(start.y()-ref->y(),2) )); + + //Number of frames in animation. Increase for smother motion + double step = 300.0; + + //Random values that give the eliptical pattern to the orbit. Between 0.4 and 2.3 + double xrand = 0.4; //(qrand()%10+4)/10.0; + double yrand = 0.4; //(qrand()%10+4)/10.0; + + double theta = 1.5707963; + //double theta = aTan((start.x() - ref->x())/(start.y() - ref->y())); + QMatrix rotation = QMatrix(qCos(theta), qSin(theta), -qSin(theta), qCos(theta), -ref->x(), -ref->y()); + qDebug() << rotation; + //qDebug() << "Starting Point" << start; + //qDebug() << "Angle" << theta; + //qDebug() << "Distance" << radius; + //qDebug() << "Center" << *ref; + + QPoint firstP = (QPoint(ref->x() + xrand*start.x()*(qCos(0/step) -qSin(0/step)), ref->y() + yrand*start.y()*(qCos(0/step) -qSin(0/step)))); + QPoint rotFP = rotation.map(firstP); + qDebug() << "First Point" << firstP; + qDebug() << "Rotation by Matrix" << rotFP; + QPoint lastP = (QPoint(ref->x() + xrand*start.x()*(qCos(PI/step) -qSin(PI/step)), ref->y() + yrand*start.y()*(qCos(PI/step) -qSin(PI/step)))); + orbit->setKeyValueAt(0, firstP); + orbit->setKeyValueAt(1, lastP); + //path.push_back(firstP); + + //Loops through all steps and creates all the points of the orbit + for(int i=1; i<step; i++) { + //Calculates the new point, including gravitational pull and eccentricity. Goes from 0 to 2PI in steps. + double newX = ref->x() + xrand*start.x()*(qCos((PI*i)/step) - qSin((PI*i)/step)); + double newY = ref->y() + yrand*start.y()*(qSin((PI*i)/step) + qCos((PI*i)/step)); + + //Creates a new point and creates a key as part of the animation + QPoint newLoc = (QPoint(newX, newY)); + orbit->setKeyValueAt(i/step, newLoc); + //path.push_back(newLoc); + } + //Sets the time for a full orbit. Increasing makes the orbit slower. + //path.push_back(lastP); + } +private slots: + /*void LoopChanged(int loop){ + //Adjust the orbit animation a bit + if(loop >= 0) { + orbit->setStartValue(orbit->endValue()); //start at the previous end point + orbit->setEndValue(path.at(loop%1000)); + orbit->setDuration(10); + } + }*/ + void stopped(){ planet->hide();} + +public: + Grav(QWidget *parent) : QParallelAnimationGroup(parent){ + planet = new QWidget(parent); + range = parent->size(); + QPoint center = QRect(QPoint(0,0), parent->size()).center();; + + //Creates a random planet size. Between 12 and 45 pixels + int planet_radius = qRound(1.75* ((qrand()%20)+7) ); + + //Creates a random color in RGB, then creates a circular gradient + QString color = "rgba(" + QString::number(qrand() % 256) + ", " + QString::number(qrand() % 256) + ", " + QString::number(qrand() % 256); + QString style = "background-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 " + color+ + ", 255)" + " , stop:0.83871 " + color + ", 140)" + " , stop:0.99 rgba(0, 0, 0, 255), stop:1 transparent);"; + planet->setStyleSheet(style); + + //setup the orbit animation + orbit = new QPropertyAnimation(planet); + orbit->setPropertyName("pos"); + orbit->setTargetObject(planet); + + //Creates the random position of the planet, making sure it isn't too close to the sun + QRect invalid = QRect(center+QPoint(-50,-50), center+QPoint(50,50)); + QPoint tmp = center; + while(invalid.contains(tmp)){ + int randwidth = qrand()%(range.width() - 2*planet_radius) + planet_radius; + int randheight = qrand()%(range.height()- 2*planet_radius) + planet_radius; + tmp = QPoint(randwidth, randheight); + } + + //Creates all frames for the animation + setupLoop(tmp, ¢er); + this->addAnimation(orbit); + planet->show(); + + //Ensures the screensaver will not stop until the user wishes to login or it times out + this->setLoopCount(3); //number of orbits + orbit->setDuration( qrand() %1000 + 19000); //20 second orbits + //orbit->setEndValue(path.at(0)); + //LoopChanged(0); //load initial values + + //Sets the initial size and location of the planet + planet->setGeometry(QRect(orbit->startValue().toPoint(), QSize(planet_radius, planet_radius))); + //connect(this, SIGNAL(currentLoopChanged(int)), this, SLOT(LoopChanged(int)) ); + connect(this, SIGNAL(finished()), this, SLOT(stopped()) ); + } + ~Grav(){} + +}; + +class GravAnimation : public BaseAnimGroup{ + Q_OBJECT +private: + QList<Grav*> planets; + QWidget *sun; + QPropertyAnimation *wobble; + +private slots: + void checkFinished(){ + int running = 0; + for(int i=0; i<this->animationCount(); i++){ + if(this->animationAt(i)->state()==QAbstractAnimation::Running){ running++; } + } + if(running<=1){ wobble->stop(); emit wobble->finished();} + } + +public: + GravAnimation(QWidget *parent) : BaseAnimGroup(parent){} + ~GravAnimation(){ + sun->deleteLater(); + while(planets.length()>0){ planets.takeAt(0)->deleteLater(); } + } + + void LoadAnimations(){ + //Creates the sun, which is a thin shell with a gradient from green to yellow + sun = new QWidget(canvas); + QPoint center = QRect(QPoint(0,0), canvas->size()).center(); + QString sunstyle = QStringLiteral("background-color:qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, ") + + QStringLiteral("stop:0 rgba(0, 0, 0, 0), stop:0.38 rgba(0, 0, 0, 0), stop:0.4 rgba(82, 121, 76, 33), stop:0.5 rgba(159, 235, 148, 64), ") + + QStringLiteral("stop:0.6 rgba(255, 238, 150, 129), stop:0.7 rgba(0, 0, 0, 0));"); + sun->setStyleSheet(sunstyle); + + //Creates the sun's pulsing animation + wobble = new QPropertyAnimation(sun); + wobble->setPropertyName("geometry"); + wobble->setTargetObject(sun); + QRect initgeom = QRect(center-QPoint(30,30), QSize(60, 60)); + wobble->setStartValue(initgeom); + wobble->setKeyValueAt(0, initgeom ); //starting point + wobble->setKeyValueAt(1, initgeom ); //starting point + wobble->setKeyValueAt(0.5, QRect(center-QPoint(45,45), QSize(90, 90))); //starting point + wobble->setDuration(2000); + wobble->setLoopCount(-1); + this->addAnimation(wobble); + sun->show(); + sun->setGeometry(initgeom); + + //Gives the screensaver a black background + //canvas->setStyleSheet("background: black;"); + + //Pulls number of planets from settings, with 10 as default + int number = readSetting("planets/number",qrand()%5+3).toInt(); + + //Loops through all planets and sets up the animations, then adds them to the base group and vector, which + //qDebug() << "Starting planets"; + for(int i=0; i<number; i++){ + Grav *tmp = new Grav(canvas); + this->addAnimation(tmp); + connect(tmp, SIGNAL(finished()), this, SLOT(checkFinished())); + planets << tmp; + } + } + +}; +#endif diff --git a/src-qt5/core/lumina-desktop/src-screensaver/animations/ImageSlideshow.h b/src-qt5/core/lumina-desktop/src-screensaver/animations/ImageSlideshow.h new file mode 100644 index 00000000..81bc2b35 --- /dev/null +++ b/src-qt5/core/lumina-desktop/src-screensaver/animations/ImageSlideshow.h @@ -0,0 +1,165 @@ +//=========================================== +// Lumina-DE source code +// Copyright (c) 2015, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#ifndef _LUMINA_DESKTOP_SCREEN_SAVER_IMAGESLIDESHOW_ANIMATION_H +#define _LUMINA_DESKTOP_SCREEN_SAVER_IMAGESLIDESHOW_ANIMATION_H + +#include "global-includes.h" +#include "BaseAnimGroup.h" + +class ImageSlideshow: public QParallelAnimationGroup{ + Q_OBJECT +private: + QLabel *image; + QPropertyAnimation *bounce, *fading; + QPixmap pixmap; + QStringList imageFiles; + QString imagePath, scriptPath, curpixmap; + QSize screenSize; + bool animate, scriptLoad; + +private: + void setupAnimation() { + //Choose between starting from top or bottom at random + if(qrand() % 2) { + bounce->setKeyValueAt(0, QPoint(0,screenSize.height()-image->height())); + bounce->setKeyValueAt(0.25, QPoint((screenSize.width()-image->width())/2,0)); + bounce->setKeyValueAt(0.5, QPoint(screenSize.width()-image->width(),screenSize.height()-image->height())); + bounce->setKeyValueAt(0.75, QPoint((screenSize.width()-image->width())/2,0)); + bounce->setKeyValueAt(1, QPoint(0,screenSize.height()-image->height())); + }else{ + bounce->setKeyValueAt(0, QPoint(0,0)); + bounce->setKeyValueAt(0.25, QPoint((screenSize.width()-image->width())/2,screenSize.height()-image->height())); + bounce->setKeyValueAt(0.5, QPoint(screenSize.width()-image->width(),0)); + bounce->setKeyValueAt(0.75, QPoint((screenSize.width()-image->width())/2,screenSize.height()-image->height())); + bounce->setKeyValueAt(1, QPoint(0,0)); + } + } + + void chooseImage() { + /*if(scriptLoad){ + QProcess process; + process.start("/home/zwelch/test.sh"); + process.waitForFinished(1000); + QByteArray output = process.readAllStandardOutput(); + //qDebug() << output; + //pixmap.load(randomFile); + }else{*/ + //File Load + QString randomFile = curpixmap; + if(imageFiles.size()>1 || curpixmap.isEmpty()){ + while(curpixmap==randomFile){ randomFile = imagePath+imageFiles[qrand() % imageFiles.size()]; } + } + if(curpixmap!=randomFile){ + curpixmap = randomFile; //save this for later + //no need to load the new file or change the label + pixmap.load(randomFile); + //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) + //Scale the pixmap to keep the aspect ratio instead of resizing the label itself + if(pixmap.width() >= (screenSize.width()-10) || pixmap.height() >= (screenSize.height()-10) ){ + pixmap = pixmap.scaled(screenSize*(3.0/4.0), Qt::KeepAspectRatio); + } + //Set pixmap to the image label + image->setPixmap(pixmap); + image->resize(pixmap.size()); + } + //} + + } + +private slots: + void LoopChanged(){ + //Load a new random image. Resize the label based on the image's size + chooseImage(); + setupAnimation(); + } + void stopped(){ image->hide();} + +public: + ImageSlideshow(QWidget *parent, QString path, bool animate, bool scriptLoad, QString scriptPath) : QParallelAnimationGroup(parent){ + imagePath = path; + image = new QLabel(parent); + screenSize = parent->size(); + this->animate = animate; + this->scriptLoad = scriptLoad; + this->scriptPath = scriptPath; + + //Generate the list of files in the directory + imageFiles = QDir(imagePath).entryList(QDir::Files); + //Ensure all the files are actually images + for(int i=0; i<imageFiles.length(); i++){ + if(QImageReader::imageFormat(imagePath+"/"+imageFiles[i]).isEmpty()){ imageFiles.removeAt(i); i--; } + } + if(imageFiles.empty()){ + qDebug() << "Current image file path has no files."; + image->setText("No image files found:\n"+imagePath); + }else{ + //Change some default settings for the image. If scaledContents is false, the image will be cut off if resized + image->setScaledContents(true); + image->setAlignment(Qt::AlignHCenter); + //Load a random initial image + chooseImage(); + } + + //Create the animation that moves the image across the screen + bounce = new QPropertyAnimation(image, "pos", parent); + + //Add the animation that fades the image in and out + QGraphicsOpacityEffect *eff = new QGraphicsOpacityEffect(parent); + image->setGraphicsEffect(eff); + fading = new QPropertyAnimation(eff,"opacity"); + fading->setKeyValueAt(0, 0); + fading->setKeyValueAt(0.20, 1); + fading->setKeyValueAt(0.80, 1); + fading->setKeyValueAt(1, 0); + this->addAnimation(fading); + + setupAnimation(); + image->show(); + //Only add the animation if set in the configuration file + if(animate) + this->addAnimation(bounce); + else + //If no animation, center the image in the middle of the screen + image->move(QPoint((parent->width()-image->width())/2,(parent->height()-image->height())/2)); + + //Loop through 15 times for a total for 2 minutes + this->setLoopCount(15); + bounce->setDuration(8000); + fading->setDuration(8000); + + connect(this, SIGNAL(currentLoopChanged(int)), this, SLOT(LoopChanged()) ); + connect(this, SIGNAL(finished()), this, SLOT(stopped()) ); + } + ~ImageSlideshow(){} + +}; + +class ImageAnimation: public BaseAnimGroup{ + Q_OBJECT +public: + ImageAnimation(QWidget *parent) : BaseAnimGroup(parent){} + ~ImageAnimation(){ + this->stop(); + } + + void LoadAnimations(){ + canvas->setStyleSheet("background: black;"); + //Load the path of the images from the configuration file (default /usr/local/backgrounds/) + QString imagePath = readSetting("path", LOS::LuminaShare()+"../wallpapers/").toString(); + //Load whether to animate the image (default true) + bool animate = readSetting("animate", true).toBool(); + bool scriptLoad = readSetting("scriptLoad", true).toBool(); + QString scriptPath; + if(scriptLoad){ + scriptPath = readSetting("scriptPath", "/usr/local/backgrounds/script.sh").toString(); + } + ImageSlideshow *tmp = new ImageSlideshow(canvas, imagePath, animate, scriptLoad, scriptPath); + this->addAnimation(tmp); + } + +}; +#endif diff --git a/src-qt5/core/lumina-desktop/src-screensaver/animations/SampleAnimation.h b/src-qt5/core/lumina-desktop/src-screensaver/animations/SampleAnimation.h new file mode 100644 index 00000000..c7a8b237 --- /dev/null +++ b/src-qt5/core/lumina-desktop/src-screensaver/animations/SampleAnimation.h @@ -0,0 +1,45 @@ +//=========================================== +// Lumina-DE source code +// Copyright (c) 2015, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +// This class is the sample plugin for a ScreenSaver animation +//=========================================== +#ifndef _LUMINA_DESKTOP_SCREEN_SAVER_SAMPLE_ANIMATION_H +#define _LUMINA_DESKTOP_SCREEN_SAVER_SAMPLE_ANIMATION_H + +#include "global-includes.h" +#include "BaseAnimGroup.h" + +class SampleAnimation : public BaseAnimGroup{ + Q_OBJECT +private: + QWidget *ball; + +public: + SampleAnimation(QWidget *parent) : BaseAnimGroup(parent){} + ~SampleAnimation(){ this->stop(); delete ball; } + + void LoadAnimations(){ + //qDebug() << "Loading Sample Animation"; + ball = new QWidget(canvas); + //This creates a red "ball" on the widget which is going to expand/contract in the center of the screen + ball->setStyleSheet("background: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.341, fy:0.796, stop:0.00531915 rgba(107, 10, 10, 255), stop:0.521277 rgba(170, 10, 10, 255), stop:0.957447 rgba(200, 0, 0, 255), stop:0.994681 rgba(0, 0, 0, 225), stop:1 rgba(255, 255, 255, 0));"); + //Now setup the movements + QPropertyAnimation *move = new QPropertyAnimation(ball,"geometry"); + QPoint ctr(canvas->width()/2, canvas->height()/2); + QRect initgeom(ctr-QPoint(12,12), QSize(24,24) ); + move->setKeyValueAt(0, initgeom ); //starting point + move->setKeyValueAt(1, initgeom ); //ending point (same as start for continuity) + int size = canvas->width(); + if(size > canvas->height()){ size = canvas->height(); } + move->setKeyValueAt(0.5, QRect(ctr-QPoint(size/2, size/2), QSize(size,size))); //touch the edge of the screen + move->setDuration(10000); //10 seconds + this->addAnimation(move); + this->setLoopCount(10); //repeat 10 times + ball->show(); + } + +}; +#endif diff --git a/src-qt5/core/lumina-desktop/src-screensaver/animations/Text.h b/src-qt5/core/lumina-desktop/src-screensaver/animations/Text.h new file mode 100644 index 00000000..bdde5ba2 --- /dev/null +++ b/src-qt5/core/lumina-desktop/src-screensaver/animations/Text.h @@ -0,0 +1,100 @@ +//=========================================== +// Lumina-DE source code +// Copyright (c) 2015, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#ifndef _LUMINA_DESKTOP_SCREEN_SAVER_TEXT_ANIMATION_H +#define _LUMINA_DESKTOP_SCREEN_SAVER_TEXT_ANIMATION_H + +#include "global-includes.h" +#include "BaseAnimGroup.h" +#include <QParallelAnimationGroup> +#include <QtMath> + +#include <unistd.h> + +class Text: public QParallelAnimationGroup{ + Q_OBJECT +private: + QLabel *text; + QPropertyAnimation *movement; + QSize range; + QPoint v; + bool bounce; + +private slots: + void LoopChanged(){ + movement->setStartValue(movement->endValue()); + QPoint currLoc = movement->startValue().toPoint(); + bounce = !(currLoc.y() < 100 or currLoc.y() > range.height()-100 or currLoc.x() > range.width()-100 or currLoc.x() < 100); + if((currLoc.y() < 10 or currLoc.y() > range.height()-40) and !bounce) { + v.setY((v.y() * -1) + (qrand() % 20 - 10)); + }else if((currLoc.x() > range.width()-10 or currLoc.x() < 10) and !bounce) { + v.setX((v.x() * -1) + (qrand() % 20 - 10)); + } + currLoc.setX(currLoc.x() + v.x()); + currLoc.setY(currLoc.y() + v.y()); + movement->setEndValue(currLoc); + } + void stopped(){ qDebug() << "Text Stopped"; text->hide();} + +public: + Text(QWidget *parent, QString display) : QParallelAnimationGroup(parent){ + text = new QLabel(parent); + range = parent->size(); + QPoint center = QRect( QPoint(0,0), parent->size()).center(); + + QString color = "rgba(" + QString::number(qrand() % 206 + 50) + ", " + QString::number(qrand() % 206 + 50) + ", " + QString::number(qrand() % 206 + 50); + text->setStyleSheet("QLabel {background-color: transparent; color: " + color + "); }"); + text->setFont(QFont("Courier", 24, QFont::Bold)); + text->setText(display); + QFontMetrics metrics(text->font()); + text->setMinimumSize(QSize( metrics.horizontalAdvance(text->text())+10, metrics.height()*text->text().count("\n") +10)); + + movement = new QPropertyAnimation(text); + movement->setPropertyName("pos"); + movement->setTargetObject(text); + + this->addAnimation(movement); + text->show(); + v.setX((qrand() % 100 + 50) * qPow(-1, qrand() % 2)); + v.setY((qrand() % 100 + 50) * qPow(-1, qrand() % 2)); + movement->setStartValue(center); + //Ensures the screensaver will not stop until the user wishes to login or it times out + this->setLoopCount(200); //number of wall bounces + movement->setDuration(200); + movement->setEndValue(QPoint(qrand() % (int)range.height(), qrand() % range.width())); + LoopChanged(); //load initial values + + connect(this, SIGNAL(currentLoopChanged(int)), this, SLOT(LoopChanged()) ); + connect(this, SIGNAL(finished()), this, SLOT(stopped()) ); + } + ~Text(){} + +}; + +class TextAnimation : public BaseAnimGroup{ + Q_OBJECT +public: + TextAnimation(QWidget *parent) : BaseAnimGroup(parent){} + ~TextAnimation(){ + this->stop(); + } + + void LoadAnimations(){ + canvas->setStyleSheet("background: black;"); + //Read off the text that needs to be displayed + QString textToShow = readSetting("text", "").toString(); + if(textToShow.isEmpty()){ + char hname[300]; + gethostname(hname, 300); + textToShow = QString::fromLocal8Bit(hname); + } + // Now create the animation + Text *tmp = new Text(canvas, textToShow); + this->addAnimation(tmp); + } + +}; +#endif diff --git a/src-qt5/core/lumina-desktop/src-screensaver/animations/VideoSlideshow.h b/src-qt5/core/lumina-desktop/src-screensaver/animations/VideoSlideshow.h new file mode 100644 index 00000000..358b4bfb --- /dev/null +++ b/src-qt5/core/lumina-desktop/src-screensaver/animations/VideoSlideshow.h @@ -0,0 +1,85 @@ +//=========================================== +// Lumina-DE source code +// Copyright (c) 2015, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#ifndef _LUMINA_DESKTOP_SCREEN_SAVER_VIDEOSLIDESHOW_ANIMATION_H +#define _LUMINA_DESKTOP_SCREEN_SAVER_VIDEOSLIDESHOW_ANIMATION_H + +#include "global-includes.h" +#include "BaseAnimGroup.h" + +class VideoAnimation: public BaseAnimGroup{ + Q_OBJECT +private: + QString videoPath, singleVideo; + QVideoWidget *videoWidget; + QMediaPlayer *video; + QStringList videoFiles; + bool multiple; + +private slots: + +public: + VideoAnimation(QWidget *parent) : BaseAnimGroup(parent){} + + ~VideoAnimation(){ + this->stop(); + } + + void LoadAnimations(){ + canvas->setStyleSheet("background: black;"); + + //Load the path of the videos from the configuration file (default /usr/local/videos/) + videoPath = readSetting("path","/usr/local/videos").toString(); + singleVideo = readSetting("videoLocation","").toString(); + multiple = readSetting("multiple",true).toBool(); + if(!videoPath.endsWith("/")){ videoPath.append("/"); } + + //Set whether to copy videos on two monitors or play different videos + //multimonitor = settings->value("videoSlideshow/multimonitor",true).toBool(); + + //Set up the VideoWidget + video = new QMediaPlayer(canvas, QMediaPlayer::VideoSurface); + videoWidget = new QVideoWidget(canvas); + video->setVideoOutput(videoWidget); + videoWidget->setGeometry(QRect(QPoint(0,0), canvas->size())); + + //Generate the list of files in the directory + videoFiles = QDir(videoPath).entryList(QDir::Files); + if(videoFiles.empty()){ + qDebug() << "Current video file path has no files:" << videoPath; + return; + } + + if(singleVideo.isNull()) + singleVideo = videoPath+videoFiles[0]; + + //Loading a random file from a directory + QDesktopWidget *dw = new QDesktopWidget(); + QMediaPlaylist *playlist = new QMediaPlaylist(); + if(multiple) { + for(int i = 0; i < videoFiles.size(); i++){ + playlist->addMedia(QUrl::fromLocalFile(videoPath+videoFiles[i])); + } + playlist->shuffle(); + }else{ + playlist->addMedia(QUrl::fromLocalFile(singleVideo)); + playlist->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop); + } + videoWidget->show(); + if(multiple) + video->setPlaylist(playlist); + + //Only play sound for one monitor to prevent messed up audio + if(dw->screenNumber(canvas) == 0) + video->setVolume(100); + else + video->setVolume(0); + + video->play(); + } + +}; +#endif diff --git a/src-qt5/core/lumina-desktop/src-screensaver/animations/animations.pri b/src-qt5/core/lumina-desktop/src-screensaver/animations/animations.pri new file mode 100644 index 00000000..fdc75717 --- /dev/null +++ b/src-qt5/core/lumina-desktop/src-screensaver/animations/animations.pri @@ -0,0 +1,10 @@ +SOURCES += $$PWD/BaseAnimGroup.cpp + +HEADERS += $$PWD/BaseAnimGroup.h \ + $$PWD/SampleAnimation.h \ + $${PWD}/Fireflies.h \ + $${PWD}/Grav.h \ + $${PWD}/ImageSlideshow.h \ + $${PWD}/VideoSlideshow.h \ + $${PWD}/Text.h +#FORMS += |