diff -p -up kdeartwork-4.1.2/kscreensaver/kdesavers/CMakeLists.txt.pre-effect kdeartwork-4.1.2/kscreensaver/kdesavers/CMakeLists.txt --- kdeartwork-4.1.2/kscreensaver/kdesavers/CMakeLists.txt.pre-effect 2008-05-29 08:19:55.000000000 -0300 +++ kdeartwork-4.1.2/kscreensaver/kdesavers/CMakeLists.txt 2008-09-30 13:27:41.000000000 -0300 @@ -34,9 +34,10 @@ install(TARGETS kpolygon.kss ${INSTALL_ ########### next target ############### -set(kslideshow.kss_SRCS slideshow.cpp ) +set(kslideshow.kss_SRCS slideshow.cpp slideshow_effectscfg.ui) kde4_add_ui_files(kslideshow.kss_SRCS slideshowcfg.ui ) +kde4_add_ui_files(kslideshow.kss_SRCS slideshow_effectscfg.ui ) kde4_add_executable(kslideshow.kss ${kslideshow.kss_SRCS}) diff -p -up kdeartwork-4.1.2/kscreensaver/kdesavers/slideshowcfg.ui.pre-effect kdeartwork-4.1.2/kscreensaver/kdesavers/slideshowcfg.ui --- kdeartwork-4.1.2/kscreensaver/kdesavers/slideshowcfg.ui.pre-effect 2008-01-04 22:00:44.000000000 -0200 +++ kdeartwork-4.1.2/kscreensaver/kdesavers/slideshowcfg.ui 2008-09-30 13:27:41.000000000 -0300 @@ -1,165 +1,218 @@ -<ui version="4.0" stdsetdef="1" > - <author></author> - <comment></comment> - <exportmacro></exportmacro> - <class>SlideShowCfg</class> - <widget class="QWidget" name="SlideShowCfg" > - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>400</width> - <height>243</height> - </rect> - </property> - <layout class="QGridLayout" > - <property name="margin" > - <number>0</number> - </property> - <item rowspan="1" row="7" column="0" colspan="4" > - <widget class="QCheckBox" name="mCbxSubdirectory" > - <property name="text" > - <string>&Include images from sub-folders</string> - </property> - </widget> - </item> - <item rowspan="1" row="1" column="0" colspan="3" > - <widget class="QCheckBox" name="mCbxRandom" > - <property name="text" > - <string>&Random order</string> - </property> - </widget> - </item> - <item rowspan="1" row="6" column="2" colspan="3" > - <widget class="KUrlRequester" name="mDirChooser" /> - </item> - <item rowspan="1" row="0" column="0" colspan="3" > - <widget class="QCheckBox" name="mCbxZoom" > - <property name="text" > - <string>Resi&ze images</string> - </property> - </widget> - </item> - <item row="7" column="4" > - <spacer name="spacer9" > - <property name="sizeHint" > - <size> - <width>161</width> - <height>20</height> - </size> - </property> - <property name="sizeType" > - <enum>Expanding</enum> - </property> - <property name="orientation" > - <enum>Horizontal</enum> - </property> - </spacer> - </item> - <item rowspan="1" row="6" column="0" colspan="2" > - <widget class="QLabel" name="textLabel1" > - <property name="text" > - <string>I&mage folder:</string> - </property> - <property name="buddy" stdset="0" > - <cstring>mDirChooser</cstring> - </property> - <property name="wordWrap" > - <bool>false</bool> - </property> - </widget> - </item> - <item rowspan="1" row="2" column="0" colspan="3" > - <widget class="QCheckBox" name="mCbxShowName" > - <property name="text" > - <string>Show &names</string> - </property> - </widget> - </item> - <item row="5" column="1" > - <spacer name="spacer11" > - <property name="sizeHint" > - <size> - <width>20</width> - <height>19</height> - </size> - </property> - <property name="sizeType" > - <enum>Expanding</enum> - </property> - <property name="orientation" > - <enum>Vertical</enum> - </property> - </spacer> - </item> - <item rowspan="1" row="4" column="1" colspan="2" > - <widget class="QSpinBox" name="mDelay" > - <property name="suffix" > - <string> sec</string> - </property> - <property name="specialValueText" > - <string/> - </property> - <property name="maximum" > - <number>240</number> - </property> - <property name="minimum" > - <number>1</number> - </property> - </widget> - </item> - <item row="4" column="0" > - <widget class="QLabel" name="textLabel1_2" > - <property name="text" > - <string>&Delay:</string> - </property> - <property name="buddy" stdset="0" > - <cstring>mDelay</cstring> - </property> - <property name="wordWrap" > - <bool>false</bool> - </property> - </widget> - </item> - <item rowspan="1" row="3" column="0" colspan="3" > - <widget class="QCheckBox" name="mCbxRandomPosition" > - <property name="text" > - <string>Random &position</string> - </property> - </widget> - </item> - <item rowspan="6" row="0" column="3" colspan="2" > - <widget class="QFrame" name="mPreview" > - <property name="sizePolicy" > - <sizepolicy> - <hsizetype>7</hsizetype> - <vsizetype>7</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="frameShape" > - <enum>NoFrame</enum> - </property> - <property name="frameShadow" > - <enum>Plain</enum> - </property> - </widget> - </item> - </layout> - </widget> - <layoutdefault spacing="6" margin="11" /> - <pixmapfunction>qPixmapFromMimeSource</pixmapfunction> - <includes> - <include location="local" >klineedit.h</include> - <include location="local" >kpushbutton.h</include> - </includes> - <connections> - <connection> - <sender>mCbxZoom</sender> - <signal>toggled(bool)</signal> - <receiver>mCbxRandomPosition</receiver> - <slot>setDisabled(bool)</slot> - </connection> - </connections> +<ui version="4.0" > + <class>SlideShowCfg</class> + <widget class="QWidget" name="SlideShowCfg" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>440</width> + <height>278</height> + </rect> + </property> + <layout class="QGridLayout" > + <property name="margin" > + <number>0</number> + </property> + <item row="9" column="0" colspan="4" > + <widget class="QCheckBox" name="mCbxSubdirectory" > + <property name="text" > + <string>&Include images from sub-folders</string> + </property> + </widget> + </item> + <item row="1" column="0" colspan="3" > + <widget class="QCheckBox" name="mCbxRandom" > + <property name="text" > + <string>&Random order</string> + </property> + </widget> + </item> + <item row="8" column="2" colspan="3" > + <widget class="KUrlRequester" name="mDirChooser" /> + </item> + <item row="0" column="0" colspan="3" > + <widget class="QCheckBox" name="mCbxZoom" > + <property name="text" > + <string>Resi&ze images</string> + </property> + </widget> + </item> + <item row="9" column="4" > + <spacer name="spacer9" > + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType" > + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>161</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="8" column="0" colspan="2" > + <widget class="QLabel" name="textLabel1" > + <property name="text" > + <string>I&mage folder:</string> + </property> + <property name="wordWrap" > + <bool>false</bool> + </property> + <property name="buddy" > + <cstring>mDirChooser</cstring> + </property> + </widget> + </item> + <item row="2" column="0" colspan="3" > + <widget class="QCheckBox" name="mCbxShowName" > + <property name="text" > + <string>Show &names</string> + </property> + </widget> + </item> + <item row="7" column="1" > + <spacer name="spacer11" > + <property name="orientation" > + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType" > + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>20</width> + <height>19</height> + </size> + </property> + </spacer> + </item> + <item row="6" column="1" colspan="2" > + <widget class="QSpinBox" name="mDelay" > + <property name="specialValueText" > + <string/> + </property> + <property name="suffix" > + <string> sec</string> + </property> + <property name="minimum" > + <number>1</number> + </property> + <property name="maximum" > + <number>240</number> + </property> + </widget> + </item> + <item row="6" column="0" > + <widget class="QLabel" name="textLabel1_2" > + <property name="text" > + <string>&Delay:</string> + </property> + <property name="wordWrap" > + <bool>false</bool> + </property> + <property name="buddy" > + <cstring>mDelay</cstring> + </property> + </widget> + </item> + <item row="3" column="0" colspan="3" > + <widget class="QCheckBox" name="mCbxRandomPosition" > + <property name="text" > + <string>Random &position</string> + </property> + </widget> + </item> + <item rowspan="8" row="0" column="3" colspan="2" > + <widget class="QFrame" name="mPreview" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Expanding" hsizetype="Expanding" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="frameShape" > + <enum>QFrame::NoFrame</enum> + </property> + <property name="frameShadow" > + <enum>QFrame::Plain</enum> + </property> + </widget> + </item> + <item row="4" column="0" > + <widget class="QCheckBox" name="mCbxUseCrossFade" > + <property name="text" > + <string>&Use crossfade effect</string> + </property> + </widget> + </item> + <item row="5" column="0" > + <widget class="QCheckBox" name="mCbxUsePreEffects" > + <property name="text" > + <string>Use image &effects</string> + </property> + </widget> + </item> + <item row="5" column="2" > + <widget class="QPushButton" name="btSetup" > + <property name="enabled" > + <bool>false</bool> + </property> + <property name="text" > + <string>Setup...</string> + </property> + </widget> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11" /> + <pixmapfunction>qPixmapFromMimeSource</pixmapfunction> + <customwidgets> + <customwidget> + <class>KUrlRequester</class> + <extends>QFrame</extends> + <header>kurlrequester.h</header> + </customwidget> + </customwidgets> + <includes> + <include location="local" >klineedit.h</include> + <include location="local" >kpushbutton.h</include> + </includes> + <resources/> + <connections> + <connection> + <sender>mCbxZoom</sender> + <signal>toggled(bool)</signal> + <receiver>mCbxRandomPosition</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>20</x> + <y>20</y> + </hint> + <hint type="destinationlabel" > + <x>20</x> + <y>20</y> + </hint> + </hints> + </connection> + <connection> + <sender>mCbxUsePreEffects</sender> + <signal>toggled(bool)</signal> + <receiver>btSetup</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>73</x> + <y>148</y> + </hint> + <hint type="destinationlabel" > + <x>219</x> + <y>148</y> + </hint> + </hints> + </connection> + </connections> </ui> diff -p -up kdeartwork-4.1.2/kscreensaver/kdesavers/slideshow.cpp.pre-effect kdeartwork-4.1.2/kscreensaver/kdesavers/slideshow.cpp --- kdeartwork-4.1.2/kscreensaver/kdesavers/slideshow.cpp.pre-effect 2008-07-23 05:26:37.000000000 -0300 +++ kdeartwork-4.1.2/kscreensaver/kdesavers/slideshow.cpp 2008-09-30 14:37:20.000000000 -0300 @@ -25,7 +25,6 @@ #include <QPixmap> #include <QPolygon> - #include <kconfig.h> #include <kglobal.h> #include <kapplication.h> @@ -94,11 +93,15 @@ int main( int argc, char *argv[] ) kSlideShowSaver::kSlideShowSaver( WId id ): KScreenSaver(id) { mEffect = NULL; + mPreEffect = NULL; mNumEffects = 0; mIntArray = NULL; + + readConfig(); // changed the order to get "UseCrossFade" option + + if (mUsePreEffects) registerPreEffects(effectMap); // image effects only, not transitions registerEffects(); - readConfig(); initNextScreen(); mFileIdx = 0; @@ -157,6 +160,11 @@ void kSlideShowSaver::readConfig() mDelay = config.readEntry("Delay", 10) * 1000; mSubdirectory = config.readEntry("SubDirectory", false); mRandomPosition = config.readEntry("RandomPosition", false); + mUseCrossFade = config.readEntry("UseCrossFade", false); + mUsePreEffects = config.readEntry("UsePreEffects", false); + + // only get the pre-effect name if it will be used + if (mUsePreEffects) mPreEffectName = config.readEntry("PreEffect", ""); loadDirectory(); } @@ -168,23 +176,37 @@ void kSlideShowSaver::registerEffects() int i = 0; mEffectList = new EffectMethod[64]; - mEffectList[i++] = &kSlideShowSaver::effectChessboard; - mEffectList[i++] = &kSlideShowSaver::effectMultiCircleOut; - mEffectList[i++] = &kSlideShowSaver::effectSpiralIn; - mEffectList[i++] = &kSlideShowSaver::effectSweep; - mEffectList[i++] = &kSlideShowSaver::effectMeltdown; - mEffectList[i++] = &kSlideShowSaver::effectCircleOut; - mEffectList[i++] = &kSlideShowSaver::effectBlobs; - mEffectList[i++] = &kSlideShowSaver::effectHorizLines; - mEffectList[i++] = &kSlideShowSaver::effectVertLines; - mEffectList[i++] = &kSlideShowSaver::effectRandom; - mEffectList[i++] = &kSlideShowSaver::effectGrowing; - mEffectList[i++] = &kSlideShowSaver::effectIncomingEdges; + + if (!mUseCrossFade){ + mEffectList[i++] = &kSlideShowSaver::effectChessboard; + mEffectList[i++] = &kSlideShowSaver::effectMultiCircleOut; + mEffectList[i++] = &kSlideShowSaver::effectSpiralIn; + mEffectList[i++] = &kSlideShowSaver::effectSweep; + mEffectList[i++] = &kSlideShowSaver::effectMeltdown; + mEffectList[i++] = &kSlideShowSaver::effectCircleOut; + mEffectList[i++] = &kSlideShowSaver::effectBlobs; + mEffectList[i++] = &kSlideShowSaver::effectHorizLines; + mEffectList[i++] = &kSlideShowSaver::effectVertLines; + mEffectList[i++] = &kSlideShowSaver::effectRandom; + mEffectList[i++] = &kSlideShowSaver::effectGrowing; + mEffectList[i++] = &kSlideShowSaver::effectIncomingEdges; + } else{ + mEffectList[i++] = &kSlideShowSaver::effectCrossFade; + } mNumEffects = i; // mNumEffects = 1; //...for testing } +void kSlideShowSaver::registerPreEffects(PreEffectMap &map){ +// Pay attention to the right pre-effect name. + + map["Reflect Image"] = &preEffectReflectImage; + map["Black and White"] = &preEffectBlackAndWhite; + map["Sepia"] = &preEffectSepia; + map["Negative"] = &preEffectNegative; +} + //---------------------------------------------------------------------------- int kSlideShowSaver::effectMultiCircleOut(bool aInit) @@ -691,6 +713,230 @@ int kSlideShowSaver::effectVertLines(boo return -1; } +//---------------------------------------------------------------------------- +// add a crossfade effect on the current and next images +int kSlideShowSaver::effectCrossFade(bool aInit) +{ + if (aInit){ + mw = width(); + mh = height(); + mx = my = 0; + mAlpha = 0.0; + mBenchmark.start(); + } else{ + // the crossfade effect runs smoothly in this machine? + if (mBenchmark.elapsed() > 100){ + mEffectRunning = false; + mUseCrossFade = false; + registerEffects(); + return -1; + } + mBenchmark.start(); + } + + QPainter p; + + if (mAlpha >= 1.0) + { + p.begin(this); + p.drawPixmap(mx, my, mNextScreen); + p.end(); + return -1; // end of the transition + } + else if (mAlpha < 1.0) + { + QPixmap dst = mCurrentScreen; + p.begin(&dst); + QRect rect = mNextScreen.rect(); + + QPainter p2; + QPixmap pixmap(mw, mh); + pixmap.fill(Qt::transparent); + p2.begin(&pixmap); + + rect = QRect(mx, my, mw, mh); + p2.drawPixmap(mx, my, mNextScreen); // the next image is crossfading + p2.setCompositionMode(QPainter::CompositionMode_DestinationIn); + QColor color; + color.setAlpha(mAlpha * 255); + p2.fillRect(rect, color); + p2.end(); + + p.drawPixmap(mx, my, pixmap); + p.end(); + + // draw onscreen + p.begin(this); + p.drawPixmap(mx, my, dst); + p.end(); + } + + mAlpha += 0.03; // alpha increment + + return 60; +} + +//------- from here we have pre-processed effects to apply on the images ----- + +// add a mirror effect on the image +int kSlideShowSaver::preEffectReflectImage(QImage &image, int width, int height){ + int pw, ph, px, py; + int wx = 0; // X pos of the working image + int mirrorpos = (image.height() / 3) * 2; // the Y position of the mirrored image + int line = 3; // the 'fake line' separating the image and your reflect + pw = width; // width of the screen + ph = height; // height of the screen + px = py = 0; // relative positions on the screen + + wx = (image.width() == pw) ? 0 : (image.width() - pw); // here we correct the X pos... + py = (image.width() == pw) ? 0 : 30; // add a simple space from the top of the screen + + QPainter p; + QRect rect(px, py, pw, ph); + QImage workimage(pw, ph, QImage::Format_ARGB32); + p.begin(&workimage); + + p.fillRect(rect, Qt::black); + + QImage mainimage(image.scaledToHeight(mirrorpos, Qt::SmoothTransformation)); + wx = ((pw / 2) - (mainimage.width() / 2)) + (wx / 2); // ... and here we center the image + + QImage inverted(mainimage.mirrored()); + + p.drawImage(wx, py, mainimage); + p.drawImage(wx, mirrorpos + py + line, inverted); + + p.setCompositionMode(QPainter::CompositionMode_DestinationIn); + + rect = QRect(px, mirrorpos + py + line, pw, ph); // a rect to the mirrored image + // this color is used to darken the gradient below + QColor color; + color.setAlpha(0.5 * 255); + p.fillRect(rect, color); + + // a gradient that really do the mirror effect + QLinearGradient linearGradient(rect.topLeft(), rect.bottomLeft()); + linearGradient.setColorAt(0.0, Qt::black); + linearGradient.setColorAt(0.25, Qt::transparent); + p.fillRect(rect, linearGradient); + + p.end(); + + image = workimage; + return 0; +} + +// use grayscale color tone +int kSlideShowSaver::preEffectBlackAndWhite(QImage &image, int width, int height){ + int x, y; + int gray, alpha; + int px, py; + px = py = 0; // relative positions on the screen + + QPainter p; + QRect rect(px, py, width, height); + QImage workimage(width, height, QImage::Format_ARGB32); + p.begin(&workimage); + + p.fillRect(rect, Qt::black); + + QImage mainimage(image); + + if (image.height() >= height) + mainimage = mainimage.scaledToHeight(height, Qt::SmoothTransformation); + + if (mainimage.width() >= width) + mainimage = mainimage.scaledToWidth(width, Qt::SmoothTransformation); + + for (y = 0; y < mainimage.height(); ++y) + for (x = 0; x < mainimage.width(); ++x){ + gray = qGray(mainimage.pixel(x, y)); + alpha = qAlpha(mainimage.pixel(x, y)); + mainimage.setPixel(x, y, qRgba(gray, gray, gray, alpha)); + } + + p.drawImage(px, py, mainimage); + + p.end(); + + image = workimage; + return 0; +} + +// use sepia tone +int kSlideShowSaver::preEffectSepia(QImage &image, int width, int height){ + int x, y; + int red, green, blue, alpha, gray, depth; // vars used in the image conversion + int px, py; + px = py = 0; // relative positions on the screen + + QPainter p; + QRect rect(px, py, width, height); + QImage workimage(width, height, QImage::Format_ARGB32); + p.begin(&workimage); + + p.fillRect(rect, Qt::black); + + QImage mainimage(image); + + if (image.height() >= height) + mainimage = mainimage.scaledToHeight(height, Qt::SmoothTransformation); + + if (mainimage.width() >= width) + mainimage = mainimage.scaledToWidth(width, Qt::SmoothTransformation); + + depth = 20; + for (y = 0; y < mainimage.height(); ++y) + for (x = 0; x < mainimage.width(); ++x){ + alpha = qAlpha(mainimage.pixel(x, y)); + gray = qGray(mainimage.pixel(x, y)); + + red = gray + (depth * 2); + green = gray + depth; + blue = gray; + if (red > 255) red = 255; + if (green > 255) green = 255; + + mainimage.setPixel(x, y, qRgba(red, green, blue, alpha)); + } + + p.drawImage(px, py, mainimage); + + p.end(); + + image = workimage; + return 0; +} + +// invert all pixel colors +int kSlideShowSaver::preEffectNegative(QImage &image, int width, int height){ + int px, py; + px = py = 0; + + QPainter p; + QRect rect(px, py, width, height); + QImage workimage(width, height, QImage::Format_ARGB32); + p.begin(&workimage); + + p.fillRect(rect, Qt::black); + + QImage mainimage(image); + + if (image.height() >= height) + mainimage = mainimage.scaledToHeight(height, Qt::SmoothTransformation); + + if (mainimage.width() >= width) + mainimage = mainimage.scaledToWidth(width, Qt::SmoothTransformation); + + mainimage.invertPixels(); + + p.drawImage(px, py, mainimage); + + p.end(); + + image = workimage; + return 0; +} //----------------------------------------------------------------------------- void kSlideShowSaver::restart() @@ -754,6 +1000,8 @@ void kSlideShowSaver::createNextScreen() int ww, wh, iw, ih, x, y; double fx, fy; + mCurrentScreen = mNextScreen; + if (mNextScreen.size() != size()) mNextScreen = QPixmap(size()); @@ -792,6 +1040,7 @@ void kSlideShowSaver::createNextScreen() x = ((ww - iw) >> 1) + geo.mXorg; y = ((wh - ih) >> 1) + geo.mYorg; + if (mUsePreEffects) (*effectMap[mPreEffectName])(scaledImg, width(), height()); p.drawImage(x, y, scaledImg); } else @@ -810,6 +1059,7 @@ void kSlideShowSaver::createNextScreen() x = ((ww - iw) >> 1) + geo.mXorg; y = ((wh - ih) >> 1) + geo.mYorg; + if (mUsePreEffects) (*effectMap[mPreEffectName])(scaledImg, width(), height()); p.drawImage(x, y, scaledImg); } else @@ -826,6 +1076,8 @@ void kSlideShowSaver::createNextScreen() } // bitBlt(&mNextScreen, x, y, &mImage, 0, 0, iw, ih); + + if (mUsePreEffects) (*effectMap[mPreEffectName])(mImage, width(), height()); p.drawImage(x, y, mImage); } } @@ -958,6 +1210,9 @@ kSlideShowSetup::kSlideShowSetup(QWidget SLOT(slotDirSelected(const KUrl &))); connect(this,SIGNAL(okClicked()),this,SLOT(slotOk())); connect(this,SIGNAL(helpClicked()),this,SLOT(slotHelp())); + + connect(cfg->btSetup, SIGNAL(clicked(bool)), this, SLOT(slotEffectsSetup())); + readSettings(); } @@ -978,6 +1233,8 @@ void kSlideShowSetup::readSettings() cfg->mDirChooser->setPath(config.readPathEntry("Directory", QString())); cfg->mCbxSubdirectory->setChecked(config.readEntry("SubDirectory", false)); cfg->mCbxRandomPosition->setChecked(config.readEntry("RandomPosition", false)); + cfg->mCbxUseCrossFade->setChecked(config.readEntry("UseCrossFade", false)); + cfg->mCbxUsePreEffects->setChecked(config.readEntry("UsePreEffects", false)); } @@ -993,6 +1250,8 @@ void kSlideShowSetup::writeSettings() config.writePathEntry("Directory", cfg->mDirChooser->url().path()); config.writeEntry("SubDirectory", cfg->mCbxSubdirectory->isChecked()); config.writeEntry("RandomPosition", cfg->mCbxRandomPosition->isChecked()); + config.writeEntry("UseCrossFade", cfg->mCbxUseCrossFade->isChecked()); + config.writeEntry("UsePreEffects", cfg->mCbxUsePreEffects->isChecked()); config.sync(); @@ -1031,3 +1290,124 @@ void kSlideShowSetup::slotHelp() KAboutApplicationDialog mAbout(s_aboutData, this); mAbout.exec(); } + +void kSlideShowSetup::slotEffectsSetup(){ + mEffectsSetup = new kSlideShowEffectsSetup(); + + mEffectsSetup->show(); +} + +//============================================================================= +// Class SlideShowEffectsSetup +//============================================================================= +kSlideShowEffectsSetup::kSlideShowEffectsSetup(QWidget *aParent): QDialog(aParent){ + setWindowTitle(i18n( "Setup Image Effects" )); + setModal(true); + setupUi(this); + + iconW = 96; + iconH = iconW * 0.75; // dimension factor (ex: for w:96, h will be 72; w:1024, h will be 768...) + + readSettings(); + sortOneImage(); + fillList(); + + connect(btSave, SIGNAL(clicked()), SLOT(slotSave())); + connect(btCancel, SIGNAL(clicked()), SLOT(reject())); +} + +void kSlideShowEffectsSetup::slotSave(){ + KConfigGroup config(KGlobal::config(), "Settings"); + QList<QListWidgetItem *> list; + + list = effectsList->selectedItems(); + + if (!list.isEmpty()){ + config.writeEntry("PreEffect", list.first()->text()); + config.sync(); + } + + accept(); +} + +void kSlideShowEffectsSetup::fillList(){ + QListWidgetItem *item; + QString eName; + QPixmap pix; + QImage temp; + QIcon *icon; + + effectsList->clear(); + effectsList->setIconSize(QSize(iconW, iconW)); + + kSlideShowSaver::registerPreEffects(effectMap); + + kSlideShowSaver::PreEffectMap::const_iterator iterator = effectMap.constBegin(); + + while (iterator != effectMap.constEnd()){ + temp = mainImage; + (*iterator.value())(temp, iconW, iconH); + icon = new QIcon(pix.fromImage(temp)); + item = new QListWidgetItem(*icon, iterator.key(), effectsList); + if (effectName == iterator.key()) item->setSelected(true); + + ++iterator; + } +} + +void kSlideShowEffectsSetup::sortOneImage(){ + QString filename; + int fileIndex = 0; + bool done = false; + int numfiles; + + fileList.clear(); + traverseDirectory(directory); + + numfiles = fileList.count(); + if (numfiles <= 0) return; + + do{ + fileIndex = KRandom::random() % numfiles; + if (fileIndex >= numfiles) fileIndex = 0; + filename = fileList.takeAt(fileIndex); + + if (!mainImage.load(filename)) fileList.removeAll(filename); + else done = true; + } while (!done); + + mainImage = mainImage.scaledToWidth(iconW); // use the thumbnail scale +} + +void kSlideShowEffectsSetup::traverseDirectory(const QString &dirName){ + QDir dir(dirName); + + if (!dir.exists()) return; + + dir.setFilter(QDir::Dirs|QDir::Files); + + QFileInfoList fileinfolist = dir.entryInfoList(); + QFileInfoListIterator it = fileinfolist.begin(); + + while (it != fileinfolist.end()){ + if ((it->fileName() == ".") || (it->fileName() == "..")){ + ++it; + continue; + } + if (it->isDir() && it->isReadable() && subdirectory) + traverseDirectory(it->filePath()); + else if (!it->isDir()) + fileList.append(it->filePath()); + + ++it; + } +} + +void kSlideShowEffectsSetup::readSettings(){ + KConfigGroup config(KGlobal::config(), "Settings"); + + directory = config.readPathEntry("Directory", KGlobal::dirs()->findDirs("wallpaper", "").last()); + subdirectory = config.readEntry("SubDirectory", false); + effectName = config.readEntry("PreEffect", ""); +} + diff -p -up kdeartwork-4.1.2/kscreensaver/kdesavers/slideshow_effectscfg.ui.pre-effect kdeartwork-4.1.2/kscreensaver/kdesavers/slideshow_effectscfg.ui --- kdeartwork-4.1.2/kscreensaver/kdesavers/slideshow_effectscfg.ui.pre-effect 2008-09-30 13:27:41.000000000 -0300 +++ kdeartwork-4.1.2/kscreensaver/kdesavers/slideshow_effectscfg.ui 2008-09-30 13:27:41.000000000 -0300 @@ -0,0 +1,64 @@ +<ui version="4.0" > + <class>EffectsSetup</class> + <widget class="QWidget" name="EffectsSetup" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>471</height> + </rect> + </property> + <property name="windowTitle" > + <string>Setup Image Effects</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout" > + <item> + <widget class="QLabel" name="label" > + <property name="text" > + <string>Please, choose some effect from the list below:</string> + </property> + </widget> + </item> + <item> + <widget class="QListWidget" name="effectsList" /> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout" > + <item> + <spacer name="horizontalSpacer" > + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType" > + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="btSave" > + <property name="text" > + <string>Save</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="btCancel" > + <property name="text" > + <string>Cancel</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff -p -up kdeartwork-4.1.2/kscreensaver/kdesavers/slideshow.h.pre-effect kdeartwork-4.1.2/kscreensaver/kdesavers/slideshow.h --- kdeartwork-4.1.2/kscreensaver/kdesavers/slideshow.h.pre-effect 2008-05-07 06:06:19.000000000 -0300 +++ kdeartwork-4.1.2/kscreensaver/kdesavers/slideshow.h 2008-09-30 13:27:41.000000000 -0300 @@ -8,14 +8,17 @@ #define SLIDESHOW_H #include <QTimer> -#include <QStringList> #include <QPixmap> #include <QImage> +#include <QTime> +#include <QDialog> +#include <QMap> #include <kscreensaver.h> #include <kdialog.h> #include "ui_slideshowcfg.h" +#include "ui_slideshow_effectscfg.h" class SlideShowCfg : public QWidget, public Ui::SlideShowCfg { @@ -35,7 +38,9 @@ public: virtual ~kSlideShowSaver(); typedef int (kSlideShowSaver::*EffectMethod)(bool); + typedef int (*preEffectMethod)(QImage &, int, int); + typedef QMap<QString, preEffectMethod> PreEffectMap; void readConfig(); void restart(); @@ -81,6 +86,22 @@ protected: int effectMeltdown(bool doInit); int effectSpiralIn(bool doInit); int effectMultiCircleOut(bool doInit); + int effectCrossFade(bool doInit); + +public: + + /** Only one pre-effect by time. */ + static void registerPreEffects(PreEffectMap &map); + + /** Here we pre-process some effect on the image that will be show + in the screen, before the transitions effects. Do not forget to + manualy add the effects to the registerPreEffects() method. + + Note that it must be 'static' to can be accessed outside this class */ + static int preEffectReflectImage(QImage &, int, int); + static int preEffectBlackAndWhite(QImage &, int, int); + static int preEffectSepia(QImage &, int, int); + static int preEffectNegative(QImage &, int, int); protected: void paintEvent(QPaintEvent *); @@ -100,7 +121,7 @@ protected: QStringList mRandomList; int mFileIdx; QImage mImage; - QPixmap mNextScreen; + QPixmap mCurrentScreen, mNextScreen; EffectMethod* mEffectList; EffectMethod mEffect; int mNumEffects; @@ -114,12 +135,50 @@ protected: bool mRandomPosition; int mDelay; QString mDirectory; + bool mUseCrossFade; + + // pre-effect vars + QMap<QString, preEffectMethod> effectMap; + preEffectMethod mPreEffect; + bool mUsePreEffects; + QString mPreEffectName; + int mPreEffectType; // values for state of various effects: int mx, my, mw, mh, mdx, mdy, mix, miy, mi, mj, mSubType; int mx0, my0, mx1, my1, mwait; double mfx, mfy, mAlpha, mfd; int* mIntArray; + QTime mBenchmark; +}; + + +//----------------------------------------------------------------------------- +class kSlideShowEffectsSetup: public QDialog, public Ui::EffectsSetup{ + Q_OBJECT + + public: + kSlideShowEffectsSetup(QWidget *parent = NULL); + ~kSlideShowEffectsSetup() {}; + + typedef int (*preEffectMethod)(QImage &, int, int); + + protected: + void readSettings(); + void sortOneImage(); + void fillList(); + virtual void traverseDirectory(const QString &); + + QMap<QString, preEffectMethod> effectMap; + QString directory; + QStringList fileList; + QString effectName; + QImage mainImage; + bool subdirectory; + int iconW, iconH; + + protected slots: + void slotSave(); }; @@ -140,10 +199,13 @@ protected slots: void writeSettings(); void slotDirSelected(const QString &where); void slotDirSelected(const KUrl &); + void slotEffectsSetup(); private: kSlideShowSaver *mSaver; + kSlideShowEffectsSetup *mEffectsSetup; SlideShowCfg *cfg; }; + #endif /*SLIDESHOW_H*/