You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdebase/kcontrol/background/KCrossBGRender.cc

364 lines
8.1 KiB

/*
* Copyright (C) 2008 Danilo Cesar Lemes de Paula <danilo@mandriva.com>
* Copyright (C) 2008 Gustavo Boiko <boiko@mandriva.com>
* Mandriva Conectiva
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License version 2 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <tqdom.h>
#include <tqfile.h>
#include <kdebug.h>
#include "KCrossBGRender.h"
#include <tqapplication.h>
#include <kimageeffect.h>
KCrossBGRender::KCrossBGRender(int desk, int screen, bool drawBackgroundPerScreen, TDEConfig *config): KBackgroundRenderer(desk,screen,drawBackgroundPerScreen,config)
{
useCrossEfect = false;
if ( wallpaperList()[0].endsWith("xml",false) ) {
initCrossFade(wallpaperList()[0]);
}
}
void KCrossBGRender::initCrossFade(TQString xmlFile)
{
useCrossEfect = true;
if (xmlFile.isEmpty()){
useCrossEfect = false;
return;
}
secs = 0;
timeList.empty();
// read the XMLfile
TQDomDocument xmldoc = TQDomDocument(xmlFile);
TQFile file( xmlFile );
if ( !file.open( IO_ReadOnly ) ) {
useCrossEfect = false;
return;
}
if ( !xmldoc.setContent( &file ) ) {
useCrossEfect = false;
file.close();
return;
}
file.close();
TQDomElement docElem = xmldoc.documentElement();
TQDomNode n = docElem.firstChild();
while( !n.isNull() ) {
TQDomElement e = n.toElement(); // try to convert the node to an element.
if( !e.isNull() ) {
if (e.tagName() == "starttime") {
createStartTime(e);
} else if (e.tagName() == "transition") {
createTransition(e);
} else if (e.tagName() == "static") {
createStatic(e);
}
}
n = n.nextSibling();
}
// Setting "now" state
setCurrentEvent(true);
pix = getCurrentPixmap();
useCrossEfect = true;
}
KCrossBGRender::~KCrossBGRender(){
}
TQPixmap KCrossBGRender::pixmap() {
fixEnabled();
if (!useCrossEfect){
TQPixmap p = KBackgroundRenderer::pixmap();
kdDebug() << "Inherited " << p.size() << endl;
if (p.width() == 0 && p.height() == 0){
p.convertFromImage(image());
}
return p;
}
return pix;
}
bool KCrossBGRender::needWallpaperChange(){
if (!useCrossEfect) {
return KBackgroundRenderer::needWallpaperChange();
}
bool forceChange = setCurrentEvent(); // If we change the current state
if (forceChange){ // do not matter what hapens
actualPhase = 0; // we need to change background
return true;
}
// Return false if it's not a transition
if (!current.transition) {
return false;
}
double timeLeft, timeTotal;
TQTime now = TQTime::currentTime();
timeLeft = now.secsTo(current.etime);
if (timeLeft < 0) {
timeLeft += 86400; // before midnight
}
timeTotal = current.stime.secsTo(current.etime);
if (timeTotal < 0) {
timeTotal += 86400;
}
double passed = timeTotal - timeLeft;
double timeCell = timeTotal/60; //Time cell size
//kdDebug() << "\ntimeleft:" << timeLeft << " timeTotal:" << timeTotal
// << "\npassed:" << passed << " timeCell:" << timeCell
// << "\nactualPhase: " << actualPhase << endl;
int aux = passed/timeCell;
if(actualPhase != aux){
//kdDebug() << "needWallpaperChange() => returned true" << endl;
actualPhase = passed/timeCell;
return true;
}
//kdDebug() << "needWallpaperChange() => returned false" << endl;
return false;
}
/*
* This method change the enabledEffect flag to TRUE of FALSE, according
* with multiWallpaperMode and FileName (it needs to be a XML)
*/
void KCrossBGRender::fixEnabled(){
TQString w = wallpaperList()[0];
useCrossEfect = false;
if(multiWallpaperMode() == Random || multiWallpaperMode() == InOrder){
if ( w != xmlFileName ){
// New XML File
xmlFileName = w;
if (w.endsWith("xml",false)){
initCrossFade(wallpaperList()[0]);
//useCrossEfect = true;
}else{
// Not, it's not a xml file
useCrossEfect = false;
}
}else if (w.endsWith("xml",false)){
//xmlFile doesn't change
//but it's there
useCrossEfect = true;
}else{
// it's not a XML file
useCrossEfect = false;
}
}
}
void KCrossBGRender::changeWallpaper(bool init){
fixEnabled();
if (!useCrossEfect){
KBackgroundRenderer::changeWallpaper(init);
return;
}
pix = getCurrentPixmap();
}
bool KCrossBGRender::setCurrentEvent(bool init){
TQTime now = TQTime::currentTime();
//Verify if is need to change
if (!(init || now <= current.stime || now >= current.etime )) {
return false;
}
TQValueList<KBGCrossEvent>::iterator it;
for ( it = timeList.begin(); it != timeList.end(); ++it ){
// Look for time
if ( ((*it).stime <= now && now <= (*it).etime) || //normal situation
((*it).etime <= (*it).stime && (now >= (*it).stime ||
now <= (*it).etime) ) )
{
current = *it;
actualPhase = 0;
//kdDebug() << "Cur: " << current.stime << "< now <" << current.etime << endl;
return true;
}
}
return false;
}
TQPixmap KCrossBGRender::getCurrentPixmap()
{
float alpha;
TQPixmap ret;
TQImage tmp;
TQImage p1;
if (!tmp.load(current.pix1))
return TQPixmap();
// scale the pixmap to fit in the screen
//p1 = TQPixmap(QApplication::desktop()->screenGeometry().size());
//TQPainter p(&p1);
//p.drawPixmap(p1.rect(), tmp);
//
p1 = tmp.smoothScale(TQApplication::desktop()->screenGeometry().size());
if (current.transition){
TQTime now = TQTime::currentTime();
double timeLeft,timeTotal;
TQImage p2;
if (!tmp.load(current.pix2) )
return NULL;
p2 = tmp.smoothScale(TQApplication::desktop()->screenGeometry().size());
//TQPainter p(&p2);
//p.drawPixmap(p2.rect(), tmp);
timeLeft = now.secsTo(current.etime);
if (timeLeft < 0)
timeLeft += 86400;
timeTotal = current.stime.secsTo(current.etime);
if (timeTotal < 0)
timeTotal += 86400;
alpha = (timeTotal - timeLeft)/timeTotal;
//ret = crossFade(p2,p1,alpha);
tmp = KImageEffect::blend(p2,p1,alpha);
ret.convertFromImage(tmp);
return ret;
}else{
ret.convertFromImage(p1);
return ret;
}
}
void KCrossBGRender::createStartTime(TQDomElement docElem)
{
int hour;
int minutes;
TQDomNode n = docElem.firstChild();
while( !n.isNull() ) {
TQDomElement e = n.toElement();
if( !e.isNull() ) {
if (e.tagName() == "hour"){
hour = e.text().toInt();
}else if ( e.tagName() == "minute" ){
minutes = e.text().toInt();
}
}
n = n.nextSibling();
}
secs = hour*60*60 + minutes*60;
}
void KCrossBGRender::createTransition(TQDomElement docElem)
{
int duration;
TQString from;
TQString to;
TQDomNode n = docElem.firstChild();
while( !n.isNull() ) {
TQDomElement e = n.toElement();
if( !e.isNull() ) {
if (e.tagName() == "duration"){
duration = e.text().toFloat();
}else if ( e.tagName() == "from" ){
from = e.text();
}
else if ( e.tagName() == "to" ){
to = e.text();
}
}
n = n.nextSibling();
}
TQTime startTime(0,0,0);
startTime = startTime.addSecs(secs);
TQTime endTime(0,0,0);
endTime = endTime.addSecs(secs+duration);
secs += duration;
KBGCrossEvent l = {true, from, to, startTime,endTime};
timeList.append(l);
}
void KCrossBGRender::createStatic(TQDomElement docElem)
{
int duration;
TQString file;
TQDomNode n = docElem.firstChild();
while( !n.isNull() ) {
TQDomElement e = n.toElement();
if( !e.isNull() ) {
if (e.tagName() == "duration"){
duration = e.text().toFloat();
}else if ( e.tagName() == "file" ){
file = e.text();
}
}
n = n.nextSibling();
}
TQTime startTime(0,0,0);
startTime = startTime.addSecs(secs);
TQTime endTime(0,0,0);
endTime = endTime.addSecs(secs+duration);
secs += duration;
KBGCrossEvent l = {false, file, NULL, startTime,endTime};
timeList.append(l);
}
#include "KCrossBGRender.moc"