1 /* ============================================================
2 *
3 * This file is a part of digiKam project
4 * https://www.digikam.org
5 *
6 * Date : 2003-02-16
7 * Description : a presentation tool.
8 *
9 * Copyright (C) 2006-2009 by Valerio Fuoglio <valerio dot fuoglio at gmail dot com>
10 * Copyright (C) 2009 by Andi Clemens <andi dot clemens at googlemail dot com>
11 * Copyright (C) 2003-2005 by Renchi Raju <renchi dot raju at gmail dot com>
12 * Copyright (C) 2012-2021 by Gilles Caulier <caulier dot gilles at gmail dot com>
13 * Copyright (C) 2021 by Phuoc Khanh Le <phuockhanhnk94 at gmail dot com>
14 *
15 * This program is free software; you can redistribute it
16 * and/or modify it under the terms of the GNU General
17 * Public License as published by the Free Software Foundation;
18 * either version 2, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * ============================================================ */
26
27 #include "presentationwidget.h"
28
29 // C++ includes
30
31 #include <cmath>
32 #include <cstdlib>
33 #include <ctime>
34
35 // Qt includes
36
37 #include <QCursor>
38 #include <QFont>
39 #include <QKeyEvent>
40 #include <QMouseEvent>
41 #include <QPainter>
42 #include <QPainterPath>
43 #include <QPixmap>
44 #include <QPolygon>
45 #include <QTimer>
46 #include <QWheelEvent>
47 #include <QApplication>
48 #include <QScreen>
49 #include <QWindow>
50
51 #include <QDebug>
52
53 // KDE includes
54
55 #include <klocalizedstring.h>
56
57 // Local includes
58
59 #include "digikam_config.h"
60 #include "presentationcontainer.h"
61 #include "presentationctrlwidget.h"
62 #include "presentationloader.h"
63 #include "presentation_mainpage.h"
64
65 #ifdef HAVE_MEDIAPLAYER
66 # include "presentationaudiowidget.h"
67 # include "slidevideo.h"
68 #endif
69
70 using namespace Digikam;
71
72 namespace DigikamGenericPresentationPlugin
73 {
74
75 class Q_DECL_HIDDEN PresentationWidget::Private
76 {
77
78 public:
79
Private()80 explicit Private()
81 : sharedData (nullptr),
82 imageLoader (nullptr),
83
84 #ifdef HAVE_MEDIAPLAYER
85
86 playbackWidget (nullptr),
87 videoView (nullptr),
88
89 #endif
90
91 timer (nullptr),
92 fileIndex (0),
93 effect (nullptr),
94 effectRunning (false),
95 x (0),
96 y (0),
97 w (0),
98 h (0),
99 dx (0),
100 dy (0),
101 ix (0),
102 iy (0),
103 i (0),
104 j (0),
105 subType (0),
106 x0 (0),
107 y0 (0),
108 x1 (0),
109 y1 (0),
110 wait (0),
111 fx (0),
112 fy (0),
113 alpha (0),
114 fd (0),
115 intArray (nullptr),
116 pdone (0),
117 pixelMatrix (nullptr),
118 slideCtrlWidget (nullptr),
119 mouseMoveTimer (nullptr),
120 deskX (0),
121 deskY (0),
122 deskWidth (0),
123 deskHeight (0)
124 {
125 }
126
127 PresentationContainer* sharedData;
128
129 // -------------------------
130
131 QMap<QString, EffectMethod> Effects;
132
133 PresentationLoader* imageLoader;
134 QPixmap currImage;
135
136 #ifdef HAVE_MEDIAPLAYER
137
138 PresentationAudioWidget* playbackWidget;
139 SlideVideo* videoView;
140
141 #endif
142
143 QTimer* timer;
144 int fileIndex;
145
146 EffectMethod effect;
147 bool effectRunning;
148 QString effectName;
149
150 /// values for state of various effects
151 int x;
152 int y;
153 int w;
154 int h;
155 int dx;
156 int dy;
157 int ix;
158 int iy;
159 int i;
160 int j;
161 int subType;
162 int x0;
163 int y0;
164 int x1;
165 int y1;
166 int wait;
167 double fx;
168 double fy;
169 double alpha;
170 double fd;
171 int* intArray;
172 bool pdone;
173 bool** pixelMatrix;
174
175 /// static
176 QPolygon pa;
177
178 PresentationCtrlWidget* slideCtrlWidget;
179 QTimer* mouseMoveTimer;
180
181 int deskX;
182 int deskY;
183 int deskWidth;
184 int deskHeight;
185 };
186
PresentationWidget(PresentationContainer * const sharedData)187 PresentationWidget::PresentationWidget(PresentationContainer* const sharedData)
188 : QWidget(),
189 d (new Private)
190 {
191 setAttribute(Qt::WA_DeleteOnClose);
192 setContextMenuPolicy(Qt::PreventContextMenu);
193
194 #ifdef Q_OS_WIN
195
196 setWindowFlags(Qt::Popup |
197 Qt::FramelessWindowHint |
198 Qt::WindowStaysOnTopHint);
199
200 #else
201
202 setWindowState(windowState() | Qt::WindowFullScreen);
203
204 #endif
205
206 QScreen* screen = qApp->primaryScreen();
207
208 if (QWidget* const widget = qApp->activeWindow())
209 {
210 if (QWindow* const window = widget->windowHandle())
211 {
212 screen = window->screen();
213 }
214 }
215
216 QRect deskRect = screen->geometry();
217 d->deskX = deskRect.x();
218 d->deskY = deskRect.y();
219 d->deskWidth = deskRect.width();
220 d->deskHeight = deskRect.height();
221
222 move(d->deskX, d->deskY);
223 resize(d->deskWidth, d->deskHeight);
224
225 d->sharedData = sharedData;
226
227 d->slideCtrlWidget = new PresentationCtrlWidget(this, d->sharedData);
228 d->slideCtrlWidget->hide();
229
230 int w = d->slideCtrlWidget->width() - 1;
231 d->slideCtrlWidget->move(d->deskX + d->deskWidth - w, d->deskY);
232
233 if (!d->sharedData->loop)
234 {
235 d->slideCtrlWidget->setEnabledPrev(false);
236 }
237
238 connect(d->slideCtrlWidget, SIGNAL(signalPause()),
239 this, SLOT(slotPause()));
240
241 connect(d->slideCtrlWidget, SIGNAL(signalPlay()),
242 this, SLOT(slotPlay()));
243
244 connect(d->slideCtrlWidget, SIGNAL(signalNext()),
245 this, SLOT(slotNext()));
246
247 connect(d->slideCtrlWidget, SIGNAL(signalPrev()),
248 this, SLOT(slotPrev()));
249
250 connect(d->slideCtrlWidget, SIGNAL(signalClose()),
251 this, SLOT(slotClose()));
252
253 connect(d->slideCtrlWidget, SIGNAL(signalRemoveImageFromList()),
254 this, SLOT(slotRemoveImageFromList()));
255
256 #ifdef HAVE_MEDIAPLAYER
257
258 // -- playback widget -------------------------------
259
260 d->playbackWidget = new PresentationAudioWidget(this, d->sharedData->soundtrackUrls, d->sharedData);
261 d->playbackWidget->hide();
262 d->playbackWidget->move(d->deskX, d->deskY);
263
264 // -- video preview ---------------------------------
265
266 d->videoView = new SlideVideo(this);
267
268 // TODO: pass mouse events from d->videoView to this ?
269 //d->videoView->installEventFilter(this);
270
271 connect(d->videoView, SIGNAL(signalVideoLoaded(bool)),
272 this, SLOT(slotVideoLoaded(bool)));
273
274 connect(d->videoView, SIGNAL(signalVideoFinished()),
275 this, SLOT(slotVideoFinished()));
276
277 d->videoView->hide();
278 d->videoView->resize(d->deskWidth, d->deskHeight);
279
280 #endif
281
282 // ---------------------------------------------------------------
283
284 d->fileIndex = -1; // start with -1
285 d->effect = nullptr;
286 d->effectRunning = false;
287 d->intArray = nullptr;
288 m_endOfShow = false;
289 m_simplyShow = false;
290 m_startPainter = false;
291 m_firstPainter = true;
292 d->timer = new QTimer(this);
293
294 connect(d->timer, SIGNAL(timeout()),
295 this, SLOT(slotTimeOut()));
296
297 d->pa = QPolygon(4);
298 m_buffer = QPixmap(size());
299 m_buffer.fill(Qt::black);
300
301 d->imageLoader = new PresentationLoader(d->sharedData, width(), height(), d->fileIndex);
302
303 // --------------------------------------------------
304
305 registerEffects();
306
307 if (d->sharedData->effectName == QLatin1String("Random"))
308 {
309 d->effect = getRandomEffect();
310 }
311 else
312 {
313 d->effectName = d->sharedData->effectName;
314 d->effect = d->Effects[d->sharedData->effectName];
315
316 if (!d->effect)
317 {
318 d->effect = d->Effects[QLatin1String("None")];
319 d->effectName = QLatin1String("None");
320 }
321 }
322
323 d->timer->setSingleShot(true);
324
325 if (d->sharedData->offAutoDelay)
326 {
327 d->timer->stop();
328 slotTimeOut();
329 }
330 else
331 {
332 d->timer->start(500);
333 }
334
335 // -- hide cursor when not moved --------------------
336
337 d->mouseMoveTimer = new QTimer(this);
338 d->mouseMoveTimer->setSingleShot(true);
339
340 connect(d->mouseMoveTimer, SIGNAL(timeout()),
341 this, SLOT(slotMouseMoveTimeOut()));
342
343 setMouseTracking(true);
344 slotMouseMoveTimeOut();
345
346 #ifdef HAVE_MEDIAPLAYER
347
348 if (d->sharedData->soundtrackPlay)
349 {
350 d->playbackWidget->slotPlay();
351 }
352
353 #endif
354
355 }
356
~PresentationWidget()357 PresentationWidget::~PresentationWidget()
358 {
359
360 #ifdef HAVE_MEDIAPLAYER
361
362 d->playbackWidget->slotStop();
363
364 #endif
365
366 d->timer->stop();
367 d->mouseMoveTimer->stop();
368
369 if (d->intArray)
370 {
371 delete [] d->intArray;
372 }
373
374 delete d->imageLoader;
375 delete d;
376 }
377
readSettings()378 void PresentationWidget::readSettings()
379 {
380 }
381
loadNextImage()382 void PresentationWidget::loadNextImage()
383 {
384 if (!d->currImage.isNull())
385 {
386 m_firstPainter = false;
387 m_buffer = d->currImage;
388 }
389 else
390 {
391 m_buffer = QPixmap(size());
392 m_buffer.fill(Qt::black);
393 }
394
395 d->fileIndex++;
396
397 d->imageLoader->next();
398 int num = d->sharedData->urlList.count();
399
400 if (d->fileIndex >= num)
401 {
402 if (d->sharedData->loop)
403 {
404 d->fileIndex = 0;
405 }
406 else
407 {
408 d->currImage = QPixmap(0, 0);
409 d->fileIndex = num - 1;
410 return;
411 }
412 }
413
414 if (!d->sharedData->loop)
415 {
416 d->slideCtrlWidget->setEnabledPrev(d->fileIndex > 0);
417 d->slideCtrlWidget->setEnabledNext(d->fileIndex < num - 1);
418 }
419
420 QImage img = d->imageLoader->getCurrent();
421
422 QPixmap newPixmap = QPixmap::fromImage(img);
423 QPixmap pixmap(width(), height());
424 pixmap.fill(Qt::black);
425 QPainter p(&pixmap);
426
427 p.drawPixmap((width() - newPixmap.width()) / 2,
428 (height() - newPixmap.height()) / 2, newPixmap,
429 0, 0, newPixmap.width(), newPixmap.height());
430
431 d->currImage = pixmap;
432
433 if (img.isNull())
434 {
435
436 #ifdef HAVE_MEDIAPLAYER
437
438 d->videoView->setCurrentUrl(d->imageLoader->currPath());
439
440 #endif
441
442 }
443 }
444
loadPrevImage()445 void PresentationWidget::loadPrevImage()
446 {
447 d->fileIndex--;
448 d->imageLoader->prev();
449
450 int num = d->sharedData->urlList.count();
451
452 if (d->fileIndex < 0)
453 {
454 if (d->sharedData->loop)
455 {
456 d->fileIndex = num - 1;
457 }
458 else
459 {
460 d->fileIndex = -1; // set this to -1.
461 return;
462 }
463 }
464
465 if (!d->sharedData->loop)
466 {
467 d->slideCtrlWidget->setEnabledPrev(d->fileIndex > 0);
468 d->slideCtrlWidget->setEnabledNext(d->fileIndex < num - 1);
469 }
470
471 QImage img = d->imageLoader->getCurrent();
472
473 QPixmap newPixmap = QPixmap::fromImage(img);
474 QPixmap pixmap(width(), height());
475 pixmap.fill(Qt::black);
476 QPainter p(&pixmap);
477
478 p.drawPixmap((width() - newPixmap.width()) / 2,
479 (height() - newPixmap.height()) / 2, newPixmap,
480 0, 0, newPixmap.width(), newPixmap.height());
481
482 d->currImage = pixmap;
483
484 if (img.isNull())
485 {
486
487 #ifdef HAVE_MEDIAPLAYER
488
489 d->videoView->setCurrentUrl(d->imageLoader->currPath());
490
491 #endif
492
493 }
494 }
495
printFilename()496 void PresentationWidget::printFilename()
497 {
498 if (d->currImage.isNull())
499 {
500 return;
501 }
502
503 QPainter p;
504
505 p.begin(&d->currImage);
506 p.setPen(Qt::black);
507
508 for (int x = 9 ; x <= 11 ; ++x)
509 {
510 for (int y = 31 ; y >= 29 ; --y)
511 {
512 p.drawText(x, height() - y, d->imageLoader->currFileName());
513 }
514 }
515
516 p.setPen(QColor(Qt::white));
517 p.drawText(10, height() - 30, d->imageLoader->currFileName());
518 }
519
printComments()520 void PresentationWidget::printComments()
521 {
522 if (d->currImage.isNull())
523 {
524 return;
525 }
526
527 DItemInfo info(d->sharedData->iface->itemInfo(d->imageLoader->currPath()));
528 QString comments = info.comment();
529
530 int yPos = 30; // Text Y coordinate
531
532 if (d->sharedData->printFileName)
533 {
534 yPos = 50;
535 }
536
537 QStringList commentsByLines;
538
539 uint commentsIndex = 0; // Comments QString index
540
541 while (commentsIndex < (uint)comments.length())
542 {
543 QString newLine;
544 bool breakLine = false; // End Of Line found
545 uint currIndex; // Comments QString current index
546
547 // Check minimal lines dimension
548
549 uint commentsLinesLengthLocal = d->sharedData->commentsLinesLength;
550
551 for (currIndex = commentsIndex ; (currIndex < (uint)comments.length()) && !breakLine ; ++currIndex)
552 {
553 if ((comments[currIndex] == QLatin1Char('\n')) || comments[currIndex].isSpace())
554 {
555 breakLine = true;
556 }
557 }
558
559 if (commentsLinesLengthLocal <= (currIndex - commentsIndex))
560 {
561 commentsLinesLengthLocal = (currIndex - commentsIndex);
562 }
563
564 breakLine = false;
565
566 for (currIndex = commentsIndex ; ((currIndex <= (commentsIndex + commentsLinesLengthLocal)) &&
567 (currIndex < (uint)comments.length()) && !breakLine) ; ++currIndex)
568 {
569 breakLine = (comments[currIndex] == QLatin1Char('\n')) ? true : false;
570
571 if (breakLine)
572 {
573 newLine.append(QLatin1Char(' '));
574 }
575 else
576 {
577 newLine.append(comments[currIndex]);
578 }
579 }
580
581 commentsIndex = currIndex; // The line is ended
582
583 if (commentsIndex != (uint)comments.length())
584 {
585 while (!newLine.endsWith(QLatin1Char(' ')))
586 {
587 newLine.truncate(newLine.length() - 1);
588 commentsIndex--;
589 }
590 }
591
592 commentsByLines.prepend(newLine.trimmed());
593 }
594
595 QPainter p;
596
597 p.begin(&d->currImage);
598 p.setFont(*d->sharedData->captionFont);
599
600 for (int lineNumber = 0 ; lineNumber < (int)commentsByLines.count() ; ++lineNumber)
601 {
602 p.setPen(QColor(d->sharedData->commentsBgColor));
603
604 // coefficient 1.5 is used to maintain distance between different lines
605
606 for (int x = 9 ; x <= 11 ; ++x)
607 {
608 for (int y = (int)(yPos + lineNumber * 1.5 * d->sharedData->captionFont->pointSize() + 1) ;
609 y >= (int)(yPos + lineNumber * 1.5 * d->sharedData->captionFont->pointSize() - 1) ; --y)
610 {
611 p.drawText(x, height() - y, commentsByLines[lineNumber]);
612 }
613 }
614
615 p.setPen(QColor(d->sharedData->commentsFontColor));
616 p.drawText(10, height() - (int)(lineNumber * 1.5 * d->sharedData->captionFont->pointSize() + yPos),
617 commentsByLines[lineNumber]);
618 }
619 }
620
printProgress()621 void PresentationWidget::printProgress()
622 {
623 if (d->currImage.isNull())
624 {
625 return;
626 }
627
628 QPainter p;
629 p.begin(&d->currImage);
630
631 QString progress(QString::number(d->fileIndex + 1) + QLatin1Char('/') +
632 QString::number(d->sharedData->urlList.count()));
633
634 #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
635
636 int stringLength = p.fontMetrics().horizontalAdvance(progress) * progress.length();
637
638 #else
639
640 int stringLength = p.fontMetrics().width(progress) * progress.length();
641
642 #endif
643
644 p.setPen(QColor(Qt::black));
645
646 for (int x = 9 ; x <= 11 ; ++x)
647 {
648 for (int y = 21 ; y >= 19 ; --y)
649 {
650 p.drawText(width() - stringLength - x, y, progress);
651 }
652 }
653
654 p.setPen(QColor(Qt::white));
655 p.drawText(width() - stringLength - 10, 20, progress);
656 }
657
showEndOfShow()658 void PresentationWidget::showEndOfShow()
659 {
660 m_endOfShow = true;
661 update();
662
663 d->slideCtrlWidget->setEnabledPlay(false);
664 d->slideCtrlWidget->setEnabledNext(false);
665 d->slideCtrlWidget->setEnabledPrev(false);
666 }
667
showOverlays()668 void PresentationWidget::showOverlays()
669 {
670 if (d->slideCtrlWidget->isHidden())
671 {
672 int w = d->slideCtrlWidget->width() - 1;
673 d->slideCtrlWidget->move(d->deskX + d->deskWidth - w, d->deskY);
674 d->slideCtrlWidget->show();
675 }
676
677 #ifdef HAVE_MEDIAPLAYER
678
679 if (d->playbackWidget->isHidden())
680 {
681 d->playbackWidget->move(d->deskX, d->deskY);
682 d->playbackWidget->show();
683 }
684
685 #endif
686
687 }
688
hideOverlays()689 void PresentationWidget::hideOverlays()
690 {
691 d->slideCtrlWidget->hide();
692
693 #ifdef HAVE_MEDIAPLAYER
694
695 d->playbackWidget->hide();
696
697 #endif
698
699 }
700
keyPressEvent(QKeyEvent * event)701 void PresentationWidget::keyPressEvent(QKeyEvent* event)
702 {
703 if (!event)
704 {
705 return;
706 }
707
708 #ifdef HAVE_MEDIAPLAYER
709
710 d->playbackWidget->keyPressEvent(event);
711
712 #endif
713
714 d->slideCtrlWidget->keyPressEvent(event);
715 }
716
mousePressEvent(QMouseEvent * e)717 void PresentationWidget::mousePressEvent(QMouseEvent* e)
718 {
719 if (m_endOfShow)
720 {
721 slotClose();
722 }
723
724 if (e->button() == Qt::LeftButton)
725 {
726 d->timer->stop();
727 d->slideCtrlWidget->setPaused(!d->sharedData->offAutoDelay);
728 slotNext();
729 }
730 else if ((e->button() == Qt::RightButton) && ((d->fileIndex - 1) >= 0))
731 {
732 d->timer->stop();
733 d->slideCtrlWidget->setPaused(!d->sharedData->offAutoDelay);
734 slotPrev();
735 }
736 }
737
mouseMoveEvent(QMouseEvent * e)738 void PresentationWidget::mouseMoveEvent(QMouseEvent* e)
739 {
740 setCursor(QCursor(Qt::ArrowCursor));
741 d->mouseMoveTimer->start(1000);
742
743 if (!d->slideCtrlWidget->canHide()
744
745 #ifdef HAVE_MEDIAPLAYER
746
747 || !d->playbackWidget->canHide()
748
749 #endif
750
751 )
752 {
753 return;
754 }
755
756 QPoint pos(e->pos());
757
758 if ((pos.y() > (d->deskY + 20)) &&
759 (pos.y() < (d->deskY + d->deskHeight - 20 - 1)))
760 {
761 if (!d->slideCtrlWidget->canHide()
762
763 #ifdef HAVE_MEDIAPLAYER
764
765 || !d->playbackWidget->canHide()
766
767 #endif
768
769 )
770 {
771 return;
772 }
773 else
774 {
775 hideOverlays();
776 }
777
778 return;
779 }
780
781 showOverlays();
782 }
783
wheelEvent(QWheelEvent * e)784 void PresentationWidget::wheelEvent(QWheelEvent* e)
785 {
786 if (!d->sharedData->enableMouseWheel)
787 {
788 return;
789 }
790
791 if (m_endOfShow)
792 {
793 slotClose();
794 }
795
796 int delta = e->angleDelta().y();
797
798 if (delta < 0)
799 {
800 d->timer->stop();
801 d->slideCtrlWidget->setPaused(true);
802 slotNext();
803 }
804 else if ((delta > 0) && ((d->fileIndex - 1) >= 0))
805 {
806 d->timer->stop();
807 d->slideCtrlWidget->setPaused(true);
808 slotPrev();
809 }
810 }
811
slotMouseMoveTimeOut()812 void PresentationWidget::slotMouseMoveTimeOut()
813 {
814 QPoint pos(QCursor::pos());
815
816 if ((pos.y() < (d->deskY + 20)) ||
817 (pos.y() > (d->deskY + d->deskHeight - 20 - 1)) ||
818 !d->timer->isActive() ||
819 d->slideCtrlWidget->underMouse()
820
821 #ifdef HAVE_MEDIAPLAYER
822
823 || d->playbackWidget->underMouse()
824
825 #endif
826
827 )
828 {
829 return;
830 }
831
832 setCursor(QCursor(Qt::BlankCursor));
833 }
834
paintEvent(QPaintEvent *)835 void PresentationWidget::paintEvent(QPaintEvent*)
836 {
837 QPainter p(this);
838
839 if (m_simplyShow || m_firstPainter)
840 {
841 if (d->sharedData->printFileName)
842 {
843 printFilename();
844 }
845
846 if (d->sharedData->printProgress)
847 {
848 printProgress();
849 }
850
851 if (d->sharedData->printFileComments)
852 {
853 printComments();
854 }
855
856 double ratio = devicePixelRatioF();
857 QSize fullSize = QSizeF(ratio * width(), ratio * height()).toSize();
858
859 QPixmap pixmap = d->currImage.scaled(fullSize, Qt::KeepAspectRatio,
860 Qt::SmoothTransformation);
861
862 p.drawPixmap(0, 0, width(), height(), pixmap,
863 0, 0, pixmap.width(), pixmap.height());
864
865 p.end();
866
867 m_simplyShow = false;
868
869 return;
870 }
871
872 if (m_endOfShow)
873 {
874 p.fillRect(0, 0, width(), height(), Qt::black);
875
876 QFont fn(font());
877 fn.setPointSize(fn.pointSize() + 10);
878 fn.setBold(true);
879
880 p.setFont(fn);
881 p.setPen(Qt::white);
882 p.drawText(100, 100, i18n("Slideshow Completed"));
883 p.drawText(100, 100 + 10 + fn.pointSize(), i18n("Click to Exit..."));
884
885 p.end();
886 return;
887 }
888
889 // If execution reach this line, an effect is running
890
891 p.drawPixmap(0, 0, m_buffer);
892 }
893
startPainter()894 void PresentationWidget::startPainter()
895 {
896 m_startPainter = true;
897 repaint();
898 }
899
slotPause()900 void PresentationWidget::slotPause()
901 {
902 d->timer->stop();
903 showOverlays();
904 }
905
slotPlay()906 void PresentationWidget::slotPlay()
907 {
908 hideOverlays();
909 slotTimeOut();
910 }
911
slotPrev()912 void PresentationWidget::slotPrev()
913 {
914 loadPrevImage();
915
916 if (d->currImage.isNull() || d->sharedData->urlList.isEmpty())
917 {
918 showEndOfShow();
919 return;
920 }
921
922 d->effectRunning = false;
923
924 showCurrentImage();
925 }
926
slotNext()927 void PresentationWidget::slotNext()
928 {
929 loadNextImage();
930
931 if (d->currImage.isNull() || d->sharedData->urlList.isEmpty())
932 {
933 showEndOfShow();
934 return;
935 }
936
937 d->effectRunning = false;
938
939 showCurrentImage();
940 }
941
slotClose()942 void PresentationWidget::slotClose()
943 {
944 close();
945 }
946
slotRemoveImageFromList()947 void PresentationWidget::slotRemoveImageFromList()
948 {
949 QUrl url = d->imageLoader->currPath();
950
951 // Delete or move to trash by url
952
953 d->sharedData->iface->deleteImage(url);
954
955 // Delete from list of presentation
956
957 d->sharedData->urlList.removeOne(url);
958
959 // Delete from list of mainpage
960
961 d->sharedData->mainPage->removeImageFromList(url);
962 }
963
slotVideoLoaded(bool loaded)964 void PresentationWidget::slotVideoLoaded(bool loaded)
965 {
966 if (loaded)
967 {
968
969 #ifdef HAVE_MEDIAPLAYER
970
971 slotPause();
972 d->videoView->show();
973
974 #endif
975
976 }
977 }
978
slotVideoFinished()979 void PresentationWidget::slotVideoFinished()
980 {
981
982 #ifdef HAVE_MEDIAPLAYER
983
984 d->videoView->hide();
985 slotPlay();
986
987 #endif
988
989 }
990
991 // -- Effects rules --------------------------------------------------------------------------------------------------------
992
registerEffects()993 void PresentationWidget::registerEffects()
994 {
995 d->Effects.insert(QLatin1String("None"), &PresentationWidget::effectNone);
996 d->Effects.insert(QLatin1String("Chess Board"), &PresentationWidget::effectChessboard);
997 d->Effects.insert(QLatin1String("Melt Down"), &PresentationWidget::effectMeltdown);
998 d->Effects.insert(QLatin1String("Sweep"), &PresentationWidget::effectSweep);
999 d->Effects.insert(QLatin1String("Mosaic"), &PresentationWidget::effectMosaic);
1000 d->Effects.insert(QLatin1String("Cubism"), &PresentationWidget::effectCubism);
1001 d->Effects.insert(QLatin1String("Growing"), &PresentationWidget::effectGrowing);
1002 d->Effects.insert(QLatin1String("Horizontal Lines"), &PresentationWidget::effectHorizLines);
1003 d->Effects.insert(QLatin1String("Vertical Lines"), &PresentationWidget::effectVertLines);
1004 d->Effects.insert(QLatin1String("Circle Out"), &PresentationWidget::effectCircleOut);
1005 d->Effects.insert(QLatin1String("MultiCircle Out"), &PresentationWidget::effectMultiCircleOut);
1006 d->Effects.insert(QLatin1String("Spiral In"), &PresentationWidget::effectSpiralIn);
1007 d->Effects.insert(QLatin1String("Blobs"), &PresentationWidget::effectBlobs);
1008 }
1009
effectNames()1010 QStringList PresentationWidget::effectNames()
1011 {
1012 QStringList effects;
1013
1014 effects.append(QLatin1String("None"));
1015 effects.append(QLatin1String("Chess Board"));
1016 effects.append(QLatin1String("Melt Down"));
1017 effects.append(QLatin1String("Sweep"));
1018 effects.append(QLatin1String("Mosaic"));
1019 effects.append(QLatin1String("Cubism"));
1020 effects.append(QLatin1String("Growing"));
1021 effects.append(QLatin1String("Horizontal Lines"));
1022 effects.append(QLatin1String("Vertical Lines"));
1023 effects.append(QLatin1String("Circle Out"));
1024 effects.append(QLatin1String("MultiCircle Out"));
1025 effects.append(QLatin1String("Spiral In"));
1026 effects.append(QLatin1String("Blobs"));
1027 effects.append(QLatin1String("Random"));
1028
1029 return effects;
1030 }
1031
effectNamesI18N()1032 QMap<QString, QString> PresentationWidget::effectNamesI18N()
1033 {
1034 QMap<QString, QString> effects;
1035
1036 effects[QLatin1String("None")] = i18nc("Filter Effect: No effect", "None");
1037 effects[QLatin1String("Chess Board")] = i18nc("Filter Effect: Chess Board", "Chess Board");
1038 effects[QLatin1String("Melt Down")] = i18nc("Filter Effect: Melt Down", "Melt Down");
1039 effects[QLatin1String("Sweep")] = i18nc("Filter Effect: Sweep", "Sweep");
1040 effects[QLatin1String("Mosaic")] = i18nc("Filter Effect: Mosaic", "Mosaic");
1041 effects[QLatin1String("Cubism")] = i18nc("Filter Effect: Cubism", "Cubism");
1042 effects[QLatin1String("Growing")] = i18nc("Filter Effect: Growing", "Growing");
1043 effects[QLatin1String("Horizontal Lines")] = i18nc("Filter Effect: Horizontal Lines", "Horizontal Lines");
1044 effects[QLatin1String("Vertical Lines")] = i18nc("Filter Effect: Vertical Lines", "Vertical Lines");
1045 effects[QLatin1String("Circle Out")] = i18nc("Filter Effect: Circle Out", "Circle Out");
1046 effects[QLatin1String("MultiCircle Out")] = i18nc("Filter Effect: Multi-Circle Out", "Multi-Circle Out");
1047 effects[QLatin1String("Spiral In")] = i18nc("Filter Effect: Spiral In", "Spiral In");
1048 effects[QLatin1String("Blobs")] = i18nc("Filter Effect: Blobs", "Blobs");
1049 effects[QLatin1String("Random")] = i18nc("Filter Effect: Random effect", "Random");
1050
1051 return effects;
1052 }
1053
slotTimeOut()1054 void PresentationWidget::slotTimeOut()
1055 {
1056 if (!d->effect)
1057 {
1058 return; // No effect -> bye !
1059 }
1060
1061 int tmout = -1;
1062
1063 if (d->effectRunning) // Effect under progress ?
1064 {
1065 tmout = (this->*d->effect)(false);
1066 }
1067 else
1068 {
1069 loadNextImage();
1070
1071 if (d->sharedData->offAutoDelay)
1072 {
1073 showCurrentImage();
1074 }
1075 else
1076 {
1077 if (d->currImage.isNull() || d->sharedData->urlList.isEmpty()) // End of slideshow ?
1078 {
1079 showEndOfShow();
1080 return;
1081 }
1082
1083 if (d->sharedData->effectName == QLatin1String("Random")) // Take a random effect.
1084 {
1085 if (d->currImage.isNull() || d->sharedData->urlList.isEmpty()) // End of slideshow ?
1086 {
1087 showEndOfShow();
1088 return;
1089 }
1090 }
1091 d->effectRunning = true;
1092
1093 tmout = (this->*d->effect)(true);
1094 }
1095 }
1096
1097 if (tmout <= 0) // Effect finished -> delay.
1098 {
1099 tmout = d->sharedData->delay;
1100 d->effectRunning = false;
1101 }
1102
1103 if (d->sharedData->offAutoDelay)
1104 {
1105 d->timer->stop();
1106 }
1107 else
1108 {
1109 d->timer->setSingleShot(true);
1110 d->timer->start(tmout);
1111 }
1112 }
1113
showCurrentImage()1114 void PresentationWidget::showCurrentImage()
1115 {
1116 if (d->currImage.isNull())
1117 {
1118 return;
1119 }
1120
1121 m_simplyShow = true;
1122
1123 repaint();
1124 }
1125
getRandomEffect()1126 PresentationWidget::EffectMethod PresentationWidget::getRandomEffect()
1127 {
1128 QStringList effs = d->Effects.keys();
1129 effs.removeAt(effs.indexOf(QLatin1String("None")));
1130
1131 int count = effs.count();
1132 int i = qrand() % count;
1133 QString key = effs[i];
1134 d->effectName = key;
1135
1136 return d->Effects[key];
1137 }
1138
effectNone(bool)1139 int PresentationWidget::effectNone(bool /* aInit */)
1140 {
1141 showCurrentImage();
1142
1143 return -1;
1144 }
1145
effectChessboard(bool aInit)1146 int PresentationWidget::effectChessboard(bool aInit)
1147 {
1148 if (aInit)
1149 {
1150 d->w = width();
1151 d->h = height();
1152 d->dx = 8; // width of one tile
1153 d->dy = 8; // height of one tile
1154 d->j = (d->w + d->dx - 1) / d->dx; // number of tiles
1155 d->x = d->j * d->dx; // shrinking x-offset from screen border
1156 d->ix = 0; // growing x-offset from screen border
1157 d->iy = 0; // 0 or d->dy for growing tiling effect
1158 d->y = (d->j & 1) ? 0 : d->dy; // 0 or d->dy for shrinking tiling effect
1159 d->wait = 800 / d->j; // timeout between effects
1160 }
1161
1162 if (d->ix >= d->w)
1163 {
1164 showCurrentImage();
1165 return -1;
1166 }
1167
1168 d->ix += d->dx;
1169 d->x -= d->dx;
1170 d->iy = d->iy ? 0 : d->dy;
1171 d->y = d->y ? 0 : d->dy;
1172
1173 QPainter bufferPainter(&m_buffer);
1174 QBrush brush = QBrush(d->currImage);
1175
1176 for (int y = 0 ; y < d->w ; y += (d->dy << 1))
1177 {
1178 bufferPainter.fillRect(d->ix, y + d->iy, d->dx, d->dy, brush);
1179 bufferPainter.fillRect(d->x, y + d->y, d->dx, d->dy, brush);
1180 }
1181
1182 repaint();
1183
1184 return d->wait;
1185 }
1186
effectMeltdown(bool aInit)1187 int PresentationWidget::effectMeltdown(bool aInit)
1188 {
1189 int i;
1190
1191 if (aInit)
1192 {
1193 delete [] d->intArray;
1194 d->w = width();
1195 d->h = height();
1196 d->dx = 4;
1197 d->dy = 16;
1198 d->ix = d->w / d->dx;
1199 d->intArray = new int[d->ix];
1200
1201 for (i = d->ix - 1 ; i >= 0 ; --i)
1202 {
1203 d->intArray[i] = 0;
1204 }
1205 }
1206
1207 d->pdone = true;
1208
1209 int y, x;
1210 QPainter bufferPainter(&m_buffer);
1211
1212 for (i = 0, x = 0 ; i < d->ix ; ++i, x += d->dx)
1213 {
1214 y = d->intArray[i];
1215
1216 if (y >= d->h)
1217 {
1218 continue;
1219 }
1220
1221 d->pdone = false;
1222
1223 if ((qrand() & 15) < 6)
1224 {
1225 continue;
1226 }
1227 /*
1228 bufferPainter.drawPixmap(x, y + d->dy, m_buffer, x, y, d->dx, d->h - y - d->dy);
1229 */
1230 bufferPainter.drawPixmap(x, y, d->currImage, x, y, d->dx, d->dy);
1231
1232 d->intArray[i] += d->dy;
1233 }
1234
1235 bufferPainter.end();
1236
1237 repaint();
1238
1239 if (d->pdone)
1240 {
1241 delete [] d->intArray;
1242 d->intArray = nullptr;
1243 showCurrentImage();
1244
1245 return -1;
1246 }
1247
1248 return 15;
1249 }
1250
effectSweep(bool aInit)1251 int PresentationWidget::effectSweep(bool aInit)
1252 {
1253 if (aInit)
1254 {
1255 // subtype: 0=sweep right to left, 1=sweep left to right
1256 // 2=sweep bottom to top, 3=sweep top to bottom
1257
1258 d->subType = qrand() % 4;
1259 d->w = width();
1260 d->h = height();
1261 d->dx = (d->subType == 1 ? 16 : -16);
1262 d->dy = (d->subType == 3 ? 16 : -16);
1263 d->x = (d->subType == 1 ? 0 : d->w);
1264 d->y = (d->subType == 3 ? 0 : d->h);
1265 }
1266
1267 if (d->subType == 0 || d->subType == 1)
1268 {
1269 // horizontal sweep
1270
1271 if (((d->subType == 0) && (d->x < -64)) || ((d->subType == 1) && (d->x > d->w + 64)))
1272 {
1273 showCurrentImage();
1274 return -1;
1275 }
1276
1277 int w;
1278 int x;
1279 int i;
1280
1281 for (w = 2, i = 4, x = d->x ; i > 0 ; --i, w <<= 1, x -= d->dx)
1282 {
1283 m_px = x;
1284 m_py = 0;
1285 m_psx = w;
1286 m_psy = d->h;
1287
1288 QPainter bufferPainter(&m_buffer);
1289 bufferPainter.fillRect(m_px, m_py, m_psx, m_psy, QBrush(d->currImage));
1290 bufferPainter.end();
1291
1292 repaint();
1293 }
1294
1295 d->x += d->dx;
1296 }
1297 else
1298 {
1299 // vertical sweep
1300
1301 if (((d->subType == 2) && (d->y < -64)) || ((d->subType == 3) && (d->y > d->h + 64)))
1302 {
1303 showCurrentImage();
1304 return -1;
1305 }
1306
1307 int h;
1308 int y;
1309 int i;
1310
1311 for (h = 2, i = 4, y = d->y ; i > 0 ; --i, h <<= 1, y -= d->dy)
1312 {
1313 m_px = 0;
1314 m_py = y;
1315 m_psx = d->w;
1316 m_psy = h;
1317
1318 QPainter bufferPainter(&m_buffer);
1319 bufferPainter.fillRect(m_px, m_py, m_psx, m_psy, QBrush(d->currImage));
1320 bufferPainter.end();
1321
1322 repaint();
1323 }
1324
1325 d->y += d->dy;
1326 }
1327
1328 return 20;
1329 }
1330
effectMosaic(bool aInit)1331 int PresentationWidget::effectMosaic(bool aInit)
1332 {
1333 int dim = 10; // Size of a cell (dim x dim)
1334 int margin = dim + (int)(dim / 4);
1335
1336 if (aInit)
1337 {
1338 d->i = 30; // giri totaly
1339 d->pixelMatrix = new bool*[width()];
1340
1341 for (int x = 0 ; x < width() ; ++x)
1342 {
1343 d->pixelMatrix[x] = new bool[height()];
1344
1345 for (int y = 0 ; y < height() ; ++y)
1346 {
1347 d->pixelMatrix[x][y] = false;
1348 }
1349 }
1350 }
1351
1352 if (d->i <= 0)
1353 {
1354 showCurrentImage();
1355 return -1;
1356 }
1357
1358 int w = width();
1359 int h = height();
1360
1361 QPainter bufferPainter(&m_buffer);
1362
1363 for (int x = 0 ; x < w ; x += (qrand() % margin) + dim)
1364 {
1365 for (int y = 0 ; y < h ; y += (qrand() % margin) + dim)
1366 {
1367 if (d->pixelMatrix[x][y] == true)
1368 {
1369 if (y != 0)
1370 {
1371 y--;
1372 }
1373
1374 continue;
1375 }
1376
1377 bufferPainter.fillRect(x, y, dim, dim, QBrush(d->currImage));
1378
1379 for (int i = 0 ; i < dim && (x + i) < w ; ++i)
1380 {
1381 for (int j = 0 ; j < dim && (y + j) < h ; ++j)
1382 {
1383 d->pixelMatrix[x+i][y+j] = true;
1384 }
1385 }
1386 }
1387 }
1388
1389 bufferPainter.end();
1390 repaint();
1391 d->i--;
1392
1393 return 20;
1394 }
1395
effectCubism(bool aInit)1396 int PresentationWidget::effectCubism(bool aInit)
1397 {
1398 if (aInit)
1399 {
1400 d->alpha = M_PI * 2;
1401 d->w = width();
1402 d->h = height();
1403 d->i = 150;
1404 }
1405
1406 if (d->i <= 0)
1407 {
1408 showCurrentImage();
1409 return -1;
1410 }
1411
1412 QPainterPath painterPath;
1413 QPainter bufferPainter(&m_buffer);
1414
1415 d->x = qrand() % d->w;
1416 d->y = qrand() % d->h;
1417 int r = (qrand() % 100) + 100;
1418 m_px = d->x - r;
1419 m_py = d->y - r;
1420 m_psx = r;
1421 m_psy = r;
1422
1423 QTransform transform;
1424 transform.rotate((qrand() % 20) - 10);
1425 QRect rect(m_px, m_py, m_psx, m_psy);
1426 bufferPainter.setTransform(transform);
1427 bufferPainter.fillRect(rect, QBrush(d->currImage));
1428 bufferPainter.end();
1429 repaint();
1430
1431 d->i--;
1432
1433 return 10;
1434 }
1435
effectRandom(bool)1436 int PresentationWidget::effectRandom(bool /*aInit*/)
1437 {
1438 d->fileIndex--;
1439
1440 return -1;
1441 }
1442
effectGrowing(bool aInit)1443 int PresentationWidget::effectGrowing(bool aInit)
1444 {
1445 if (aInit)
1446 {
1447 d->w = width();
1448 d->h = height();
1449 d->x = d->w >> 1;
1450 d->y = d->h >> 1;
1451 d->i = 0;
1452 d->fx = d->x / 100.0;
1453 d->fy = d->y / 100.0;
1454 }
1455
1456 d->x = (d->w >> 1) - (int)(d->i * d->fx);
1457 d->y = (d->h >> 1) - (int)(d->i * d->fy);
1458 d->i++;
1459
1460 if ((d->x < 0) || (d->y < 0))
1461 {
1462 showCurrentImage();
1463
1464 return -1;
1465 }
1466
1467 m_px = d->x;
1468 m_py = d->y;
1469 m_psx = d->w - (d->x << 1);
1470 m_psy = d->h - (d->y << 1);
1471
1472 QPainter bufferPainter(&m_buffer);
1473 bufferPainter.fillRect(m_px, m_py, m_psx, m_psy, QBrush(d->currImage));
1474 bufferPainter.end();
1475 repaint();
1476
1477 return 20;
1478 }
1479
effectHorizLines(bool aInit)1480 int PresentationWidget::effectHorizLines(bool aInit)
1481 {
1482 static int iyPos[] = { 0, 4, 2, 6, 1, 5, 3, 7, -1 };
1483
1484 if (aInit)
1485 {
1486 d->w = width();
1487 d->h = height();
1488 d->i = 0;
1489 }
1490
1491 if (iyPos[d->i] < 0)
1492 {
1493 return -1;
1494 }
1495
1496 int iPos;
1497 int until = d->h;
1498
1499 QPainter bufferPainter(&m_buffer);
1500 QBrush brush = QBrush(d->currImage);
1501
1502 for (iPos = iyPos[d->i] ; iPos < until ; iPos += 8)
1503 {
1504 bufferPainter.fillRect(0, iPos, d->w, 1, brush);
1505 }
1506
1507 bufferPainter.end();
1508 repaint();
1509
1510 d->i++;
1511
1512 if (iyPos[d->i] >= 0)
1513 {
1514 return 160;
1515 }
1516
1517 showCurrentImage();
1518
1519 return -1;
1520 }
1521
effectVertLines(bool aInit)1522 int PresentationWidget::effectVertLines(bool aInit)
1523 {
1524 static int ixPos[] = { 0, 4, 2, 6, 1, 5, 3, 7, -1 };
1525
1526 if (aInit)
1527 {
1528 d->w = width();
1529 d->h = height();
1530 d->i = 0;
1531 }
1532
1533 if (ixPos[d->i] < 0)
1534 {
1535 return -1;
1536 }
1537
1538 int iPos;
1539 int until = d->w;
1540
1541 QPainter bufferPainter(&m_buffer);
1542 QBrush brush = QBrush(d->currImage);
1543
1544 for (iPos = ixPos[d->i] ; iPos < until ; iPos += 8)
1545 {
1546 bufferPainter.fillRect(iPos, 0, 1, d->h, brush);
1547 }
1548
1549 bufferPainter.end();
1550 repaint();
1551
1552 d->i++;
1553
1554 if (ixPos[d->i] >= 0)
1555 {
1556 return 160;
1557 }
1558
1559 showCurrentImage();
1560
1561 return -1;
1562 }
1563
effectMultiCircleOut(bool aInit)1564 int PresentationWidget::effectMultiCircleOut(bool aInit)
1565 {
1566 int x, y, i;
1567 double alpha;
1568
1569 if (aInit)
1570 {
1571 startPainter();
1572 d->w = width();
1573 d->h = height();
1574 d->x = d->w;
1575 d->y = d->h >> 1;
1576 d->pa.setPoint(0, d->w >> 1, d->h >> 1);
1577 d->pa.setPoint(3, d->w >> 1, d->h >> 1);
1578 d->fy = sqrt((double)d->w * d->w + d->h * d->h) / 2;
1579 d->i = qrand() % 15 + 2;
1580 d->fd = M_PI * 2 / d->i;
1581 d->alpha = d->fd;
1582 d->wait = 10 * d->i;
1583 d->fx = M_PI / 32; // divisor must be powers of 8
1584 }
1585
1586 if (d->alpha < 0)
1587 {
1588 showCurrentImage();
1589
1590 return -1;
1591 }
1592
1593 for (alpha = d->alpha, i = d->i ; i >= 0 ; --i, alpha += d->fd)
1594 {
1595 x = (d->w >> 1) + (int)(d->fy * cos(-alpha));
1596 y = (d->h >> 1) + (int)(d->fy * sin(-alpha));
1597 d->x = (d->w >> 1) + (int)(d->fy * cos(-alpha + d->fx));
1598 d->y = (d->h >> 1) + (int)(d->fy * sin(-alpha + d->fx));
1599
1600 d->pa.setPoint(1, x, y);
1601 d->pa.setPoint(2, d->x, d->y);
1602
1603 QPainterPath painterPath;
1604 painterPath.addPolygon(QPolygon(d->pa));
1605
1606 QPainter bufferPainter(&m_buffer);
1607 bufferPainter.fillPath(painterPath, QBrush(d->currImage));
1608 bufferPainter.end();
1609
1610 repaint();
1611 }
1612
1613 d->alpha -= d->fx;
1614
1615 return d->wait;
1616 }
1617
effectSpiralIn(bool aInit)1618 int PresentationWidget::effectSpiralIn(bool aInit)
1619 {
1620 if (aInit)
1621 {
1622 update();
1623 d->w = width();
1624 d->h = height();
1625 d->ix = d->w / 8;
1626 d->iy = d->h / 8;
1627 d->x0 = 0;
1628 d->x1 = d->w - d->ix;
1629 d->y0 = d->iy;
1630 d->y1 = d->h - d->iy;
1631 d->dx = d->ix;
1632 d->dy = 0;
1633 d->i = 0;
1634 d->j = 16 * 16;
1635 d->x = 0;
1636 d->y = 0;
1637 }
1638
1639 if ((d->i == 0) && (d->x0 >= d->x1))
1640 {
1641 showCurrentImage();
1642
1643 return -1;
1644 }
1645
1646 if ((d->i == 0) && (d->x >= d->x1)) // switch to: down on right side
1647 {
1648 d->i = 1;
1649 d->dx = 0;
1650 d->dy = d->iy;
1651 d->x1 -= d->ix;
1652 }
1653 else if ((d->i == 1) && (d->y >= d->y1)) // switch to: right to left on bottom side
1654 {
1655 d->i = 2;
1656 d->dx = -d->ix;
1657 d->dy = 0;
1658 d->y1 -= d->iy;
1659 }
1660 else if ((d->i == 2) && (d->x <= d->x0)) // switch to: up on left side
1661 {
1662 d->i = 3;
1663 d->dx = 0;
1664 d->dy = -d->iy;
1665 d->x0 += d->ix;
1666 }
1667 else if ((d->i == 3) && (d->y <= d->y0)) // switch to: left to right on top side
1668 {
1669 d->i = 0;
1670 d->dx = d->ix;
1671 d->dy = 0;
1672 d->y0 += d->iy;
1673 }
1674
1675 m_px = d->x;
1676 m_py = d->y;
1677 m_psx = d->ix;
1678 m_psy = d->iy;
1679
1680 QPainter bufferPainter(&m_buffer);
1681 bufferPainter.fillRect(m_px, m_py, m_psx, m_psy, QBrush(d->currImage));
1682 bufferPainter.end();
1683 repaint();
1684
1685 d->x += d->dx;
1686 d->y += d->dy;
1687 d->j--;
1688
1689 return 8;
1690 }
1691
effectCircleOut(bool aInit)1692 int PresentationWidget::effectCircleOut(bool aInit)
1693 {
1694 int x, y;
1695
1696 if (aInit)
1697 {
1698 startPainter();
1699 d->w = width();
1700 d->h = height();
1701 d->x = d->w;
1702 d->y = d->h >> 1;
1703 d->alpha = 2 * M_PI;
1704 d->pa.setPoint(0, d->w >> 1, d->h >> 1);
1705 d->pa.setPoint(3, d->w >> 1, d->h >> 1);
1706 d->fx = M_PI / 16; // divisor must be powers of 8
1707 d->fy = sqrt((double)d->w * d->w + d->h * d->h) / 2;
1708 }
1709
1710 if (d->alpha < 0)
1711 {
1712 showCurrentImage();
1713
1714 return -1;
1715 }
1716
1717 x = d->x;
1718 y = d->y;
1719 d->x = (d->w >> 1) + (int)(d->fy * cos(d->alpha));
1720 d->y = (d->h >> 1) + (int)(d->fy * sin(d->alpha));
1721 d->alpha -= d->fx;
1722
1723 d->pa.setPoint(1, x, y);
1724 d->pa.setPoint(2, d->x, d->y);
1725
1726 QPainterPath painterPath;
1727 painterPath.addPolygon(QPolygon(d->pa));
1728 QPainter bufferPainter(&m_buffer);
1729 bufferPainter.fillPath(painterPath, QBrush(d->currImage));
1730 bufferPainter.end();
1731 repaint();
1732
1733 return 20;
1734 }
1735
effectBlobs(bool aInit)1736 int PresentationWidget::effectBlobs(bool aInit)
1737 {
1738 int r;
1739
1740 if (aInit)
1741 {
1742 d->alpha = M_PI * 2;
1743 d->w = width();
1744 d->h = height();
1745 d->i = 150;
1746 }
1747
1748 if (d->i <= 0)
1749 {
1750 showCurrentImage();
1751
1752 return -1;
1753 }
1754
1755 d->x = qrand() % d->w;
1756 d->y = qrand() % d->h;
1757 r = (qrand() % 200) + 50;
1758 m_px = d->x - r;
1759 m_py = d->y - r;
1760 m_psx = r;
1761 m_psy = r;
1762
1763 QPainterPath painterPath;
1764 painterPath.addEllipse(m_px, m_py, m_psx, m_psy);
1765 QPainter bufferPainter(&m_buffer);
1766 bufferPainter.fillPath(painterPath, QBrush(d->currImage));
1767 bufferPainter.end();
1768 repaint();
1769
1770 d->i--;
1771
1772 return 10;
1773 }
1774
1775 } // namespace DigikamGenericPresentationPlugin
1776