AlbumShaper 1.0a3
presentationWidget.cpp
Go to the documentation of this file.
1//==============================================
2// copyright : (C) 2003-2005 by Will Stokes
3//==============================================
4// This program is free software; you can redistribute it
5// and/or modify it under the terms of the GNU General
6// Public License as published by the Free Software
7// Foundation; either version 2 of the License, or
8// (at your option) any later version.
9//==============================================
10
11//Systemwide includes
12#include <qapplication.h>
13#include <qpainter.h>
14#include <qfont.h>
15#include <qtimer.h>
16#include <qcursor.h>
17#include <qpopupmenu.h>
18#include <qiconset.h>
19#include <qdir.h>
20
21//Projectwide includes
22#include "presentationWidget.h"
23#include "../../config.h"
24#include "../../backend/album.h"
26#include "../../backend/photo.h"
28
29#define USE_ANIMATION true
30#define HIDE_MOUSE_DELAY 5000
31#define TEXT_MARGIN 4
32
33#include <iostream>
34using namespace std;
35//==============================================
36SlideshowWidget::SlideshowWidget( QWidget* parent, const char* name, WFlags f ) : QWidget(parent,name,f)
37{
38 //to prevent flicker, never erase to a background color
39 setBackgroundMode( Qt::NoBackground);
40
41 //set pointers to null
42 curAlbum = NULL;
43 curCollection = NULL;
44 collectionNum = -1;
45 curPhoto = NULL;
46 photoNum = -1;
47
48 //no photo loaded yet
49 photoLoaded = false;
50
51 //not animating by default
52 animating = false;
53
54 //default animation method is immediate
56
57 //set cur and prev pointers to the two scaled images. these
58 //pointers will be exchanged when loading new images
61
62 //set delay defaults
63 initDelay = 3; //3
64 accel = 0.1; // 0.7
65 minDelay = 1; //0.01
66
67 //setup autoplay defaults, autoPlay should be set
68 //to true/false every time we begin a new slideshow
69 autoPlayDelay = 4;
70 autoPlay = true;
72
74 //---------------
75 //create timer objects and setup signals
76 animatingTimer = new QTimer();
77 connect(animatingTimer, SIGNAL(timeout()), this, SLOT(animate()) );
78
79 autoPlayTimer = new QTimer();
80 connect(autoPlayTimer, SIGNAL(timeout()), this, SLOT(advancePhoto()) );
81
82 mouseCursorTimer = new QTimer();
83 connect(mouseCursorTimer, SIGNAL(timeout()), this, SLOT(hideMouse()) );
84 //---------------
85 //ensure pixmap are same size as screen
86 QDesktopWidget *desktop = QApplication::desktop();
87 screenWidth = desktop->screenGeometry().width();
88 screenHeight = desktop->screenGeometry().height();
92 screenBuffer.fill( black );
93
96
97 //load speed icons
98 speed1.load( QString(IMAGE_PATH)+"miscImages/cheetah.png" );
99 speed2.load( QString(IMAGE_PATH)+"miscImages/rabbit.png" );
100 speed4.load( QString(IMAGE_PATH)+"miscImages/turtle.png" );
101 speed8.load( QString(IMAGE_PATH)+"miscImages/snail.png" );
102
103 //load play and pause control interfaces
104 playInterface.load( QString(IMAGE_PATH)+"buttonIcons/playPresentation.png" );
105 pauseInterface.load( QString(IMAGE_PATH)+"buttonIcons/pausePresentation.png" );
106 interfaceAlphaMask = pauseInterface.createAlphaMask();
107
108 //by default no context menu object exists
109 contextMenuShown = false;
110 contextMenuHidingBool = false;
111
112 //set widget to accept keyboard and mouse focus
113 setFocusPolicy(QWidget::StrongFocus);
114}
115//==============================================
117{
118 //stop auto-advance, animation, and hiding mouse cursor timers
119 autoPlayTimer->stop();
120 animatingTimer->stop();
121 mouseCursorTimer->stop();
122
123 //set the photo loaded bool to false to
124 //force loading the first photo the next time
125 //we start a presentation
126 photoLoaded = false;
127
128 //restore the mouse cursor if it was hidden
129 if(!mouseShown)
130 {
131 qApp->restoreOverrideCursor();
132 mouseShown = true;
133 }
134
135 //emit exiting signal indicating to hide
136 //this widget and show normal widgets again
137 emit endSlideshow();
138}
139//==============================================
141{
143 {
144 e->ignore();
145 return;
146 }
147
148 switch( e->key() )
149 {
150 case Qt::Key_Escape:
151 stop();
152 break;
153 case Qt::Key_Return:
155 break;
156 case Qt::Key_Plus:
157 case Qt::Key_Equal:
158 //if control is pressed increase font size
159 if(e->state() & Qt::ControlButton )
161 else
162 speedUp();
163 break;
164 case Qt::Key_Minus:
165 case Qt::Key_Underscore:
166 //if control is pressed decrease font size
167 if(e->state() & Qt::ControlButton )
169 else
170 slowDown();
171 break;
172 case Qt::Key_Left:
173 backupPhoto();
174 break;
175 case Qt::Key_Right:
176 advancePhoto();
177 break;
178 case Qt::Key_Up:
180 break;
181 case Qt::Key_Down:
183 break;
184 case Qt::Key_Home:
186 break;
187 case Qt::Key_End:
189 break;
190 case Qt::Key_D:
193 break;
194 default:
195 e->ignore();
196 }
197}
198//==============================================
200{
201 //if not the left mouse button ignore
202 if(e->button() != Qt::LeftButton)
203 return;
204
205 //if mouse is shown so is the control interface, check to see if
206 //user clicked one of the interface buttons, if not
207 //not advance to next photo as normal
208 if( mouseShown )
209 {
210 bool buttonClicked = false;
211 int x, y, w, h;
212 w = pauseInterface.width();
213 h = pauseInterface.height();
214 x = ( screenWidth - w ) / 2;
215 y = screenHeight - h - TEXT_MARGIN;
216
217 //check if button pressed, must be within interface
218 //region and a non-transparent pixel
219 if(e->pos().x() >= x && e->pos().y() >= y &&
220 e->pos().x() <= x+w && e->pos().y() <= y+h &&
221 interfaceAlphaMask.pixel(e->pos().x() - x, e->pos().y() - y) != 0)
222 {
223 buttonClicked = true;
224
225 //restart the countdown for hiding the mouse and interface
226 mouseCursorTimer->stop();
227 mouseCursorTimer->start( (int)HIDE_MOUSE_DELAY, TRUE );
228
229 int xMid = x + (w/2);
230 int yMid = y + (h/2);
231 int dx = e->pos().x() - xMid;
232 int dy = e->pos().y() - yMid;
233 int distSqrd = dx*dx + dy*dy;
234 //center play/pause button is 55 pixels in radius
235 if(distSqrd <= 3025)
237 //else one of the other buttons has been pressed
238 else
239 {
240 if(e->pos().x() < xMid)
241 {
242 //top left is prev photo button
243 if(e->pos().y() < yMid)
244 backupPhoto();
245 //bottom left is prev collection button
246 else
248 }
249 else
250 {
251 //top right is next photo button
252 if(e->pos().y() < yMid)
253 advancePhoto();
254 //bottom right is next collection button
255 else
257 }
258 }
259 }
260
261 }
262}
263//==============================================
265{
266 //mouse move events often are triggered when we are exiting
267 //don't restart hiding mouse in these scenarios
268 if(!photoLoaded)
269 return;
270
271 mouseCursorTimer->stop();
272
273 //restore the mouse cursor
274 //hide again if inactive for three seconds
275 //if mouse not already shown repaint
276 if(!mouseShown)
277 {
278 qApp->restoreOverrideCursor();
279 mouseShown = true;
281 }
282
283 mouseCursorTimer->start( (int)HIDE_MOUSE_DELAY, TRUE );
284}
285//==============================================
286void SlideshowWidget::contextMenuEvent ( QContextMenuEvent * e )
287{
288 //disable hiding the mouse cursor until the context menu is destroyed
289 mouseCursorTimer->stop();
290
291 //disable autoPlay temporarily while context menu is open, drop shadows look horrid if
292 //photo scrolls while menu is up anyways
293 autoPlayTimer->stop();
294
295 QPopupMenu contextMenu(this);
296 contextMenuShown = true;
297 connect( &contextMenu, SIGNAL( aboutToHide() ), this, SLOT( contextMenuHiding() ) );
298
299 if(autoPlay)
300 contextMenu.insertItem( QIconSet( QPixmap(QString(IMAGE_PATH)+"menuIcons/pause.png") ),
301 tr("Pause"), this, SLOT(toggleAutoPlay()), Key_Return );
302 else
303 contextMenu.insertItem( QIconSet( QPixmap(QString(IMAGE_PATH)+"menuIcons/play.png") ),
304 tr("Play"), this, SLOT(toggleAutoPlay()), Key_Return );
305
306 int speedUpID = contextMenu.insertItem( QIconSet( QPixmap(QString(IMAGE_PATH)+"menuIcons/speedUp.png") ),
307 tr("Speed Up"), this, SLOT(speedUp()), Key_Plus );
308 int slowDownID = contextMenu.insertItem( QIconSet( QPixmap(QString(IMAGE_PATH)+"menuIcons/slowDown.png") ),
309 tr("Slow Down"), this, SLOT(slowDown()), Key_Minus );
310
311 //if not currently playing disable speeding up/slowing down options
312 if(!autoPlay)
313 {
314 contextMenu.setItemEnabled( speedUpID, false );
315 contextMenu.setItemEnabled( slowDownID, false );
316 }
317
318 QPopupMenu navigateMenu(&contextMenu);
319 navigateMenu.insertItem( QIconSet( QPixmap(QString(IMAGE_PATH)+"menuIcons/backupPhoto.png") ),
320 tr("Backup Photo"), this, SLOT(backupPhoto()), Key_Left );
321 navigateMenu.insertItem( QIconSet( QPixmap(QString(IMAGE_PATH)+"menuIcons/advancePhoto.png") ),
322 tr("Advance Photo"), this, SLOT(advancePhoto()), Key_Right );
323 navigateMenu.insertItem( QIconSet( QPixmap(QString(IMAGE_PATH)+"menuIcons/skipToFirstPhoto.png") ),
324 tr("Skip to First Photo"), this, SLOT(skipToFirstPhoto()), Key_Home );
325 navigateMenu.insertItem( QIconSet( QPixmap(QString(IMAGE_PATH)+"menuIcons/skipToLastPhoto.png") ),
326 tr("Skip to Last Photo"), this, SLOT(skipToLastPhoto()), Key_End );
327 navigateMenu.insertItem( QIconSet( QPixmap(QString(IMAGE_PATH)+"menuIcons/backupCollection.png") ),
328 tr("Backup Collection"), this, SLOT(backupCollection()), Key_Up );
329 navigateMenu.insertItem( QIconSet( QPixmap(QString(IMAGE_PATH)+"menuIcons/advanceCollection.png") ),
330 tr("Advance Collection"), this, SLOT(advanceCollection()), Key_Down );
331 contextMenu.insertItem( tr("Navigate"), &navigateMenu );
332
333 contextMenu.insertItem( QIconSet( QPixmap(QString(IMAGE_PATH)+"menuIcons/increaseTextSize.png") ),
334 tr("Increase Text Size"), this, SLOT(increaseTextSize()), CTRL+Key_Plus );
335 contextMenu.insertItem( QIconSet( QPixmap(QString(IMAGE_PATH)+"menuIcons/decreaseTextSize.png") ),
336 tr("Decrease Text Size"), this, SLOT(decreaseTextSize()), CTRL+Key_Minus );
337
338 contextMenu.insertItem( QIconSet( QPixmap(QString(IMAGE_PATH)+"menuIcons/exit.png") ),
339 tr("Exit"), this, SLOT(stop()), Key_Escape );
340
341 contextMenu.exec( QPoint(e->globalX(), e->globalY()) );
342 contextMenuShown = false;
343}
344//==============================================
346{
348
349 //start back up timer for hiding the mouse cursor
350 mouseCursorTimer->start( (int)HIDE_MOUSE_DELAY, TRUE );
351
352 //if autoPlay is enabled start that timer back up too
353 if(autoPlay)
354 autoPlayTimer->start( (int)1000*autoPlayDelay, TRUE );
355}
356//==============================================
358{
359 if(autoPlay)
360 {
361 autoPlayTimer->stop();
362 autoPlay = false;
363 refreshScreen();
364 }
365 else
366 {
368 autoPlay = true;
370 autoPlayTimer->start( (int)1000*autoPlayDelay, TRUE );
371 }
372}
373//==============================================
375{
376 qApp->setOverrideCursor( QCursor(Qt::BlankCursor));
377 mouseShown = false;
379}
380//==============================================
381void SlideshowWidget::paintEvent( QPaintEvent * )
382{
383 //blit the screen buffer to the screen
384 bitBlt( this, 0, 0, &screenBuffer,
385 0, 0, screenBuffer.width(), screenBuffer.height(),
386 CopyROP, true );
387}
388//==============================================
390{
391 //exchange prev and curr pointers
392 QImage* tmp = prevImage;
394 currImage = tmp;
395
396 //scale full size image to fit screen
399 photoLoaded = true;
400}
401//==============================================
403{
404 QString tempString = "";
405 int x, y;
406
407 paintBufferCurr->fill(black);
408 QPainter p;
409 //------------------------------
410 //paint photo
411 p.begin( paintBufferCurr );
412 p.drawImage( (paintBufferCurr->width() - currImage->width() ) / 2,
413 (paintBufferCurr->height() - currImage->height() ) / 2,
414 *currImage );
415 //------------------------------
416 //setup font stuff for writing text
417 p.setPen(QColor("black"));
418 QFont f( "times", fontSize, QFont::Bold );
419 QFontMetrics fm( f );
420 p.setFont( f );
421 //------------------------------
422 //paint description
423 tempString = curPhoto->getDescription();
424 if(tempString.stripWhiteSpace().length() > 0)
425 {
426 x = TEXT_MARGIN;
427 y = screenHeight - TEXT_MARGIN - fm.height() - 2*TL_TextBorder.height();
428 //-------
429 //top left corner
430 p.drawImage( x, y, TL_TextBorder );
431
432 //top edge
433 p.drawImage( QRect( x + TL_TextBorder.width(), y,
434 fm.width(tempString), TL_TextBorder.height() ),
436
437 //top right corner
438 p.drawImage( x + TL_TextBorder.width() + fm.width(tempString),
439 y, TR_TextBorder );
440 //-------
441 //left edge
442 p.drawImage( QRect( x,
443 y + TL_TextBorder.height(),
444 TL_TextBorder.width(), fm.height() ),
446
447 //right edge
448 p.drawImage( QRect( x + TL_TextBorder.width() + fm.width(tempString),
449 y + TL_TextBorder.height(),
450 TL_TextBorder.width(), fm.height() ),
452 //-------
453 //bottom left corner
454 p.drawImage( x,
455 y + TL_TextBorder.height() + fm.height(), BL_TextBorder );
456
457 //bottom edge
458 p.drawImage( QRect( x + TL_TextBorder.width(),
459 y + TL_TextBorder.height() + fm.height(),
460 fm.width(tempString), TL_TextBorder.height() ),
462
463 //bottom right corner
464 p.drawImage( x + TL_TextBorder.width() + fm.width(tempString),
465 y + TL_TextBorder.height() + fm.height(), BR_TextBorder );
466 //-------
467 p.fillRect( x + TL_TextBorder.width(), y + TL_TextBorder.height(),
468 fm.width(tempString), fm.height(), QBrush(QColor("white")) );
469 p.drawText( x + TL_TextBorder.width(), y + TL_TextBorder.height() + fm.ascent(), tempString );
470 }
471 //------------------------------
472 p.end();
473}
474//==============================================
475void SlideshowWidget::beginSlideshow(Album* albm, Subalbum* startCollection, Photo* startPhoto)
476{
477 autoPlay = true;
478 autoPlayDelay = 4;
480 displayDebugMessages = false;
481 fontSize = 24;
482
483 //store album handle and show cover page
484 curAlbum = albm;
485
486 //determine presentation resources path
487 QString presentationResourcesPath;
488 QDir tempDir( THEMES_PATH );
489
490 //if theme installed on system using its resources
491 if( tempDir.exists( THEMES_PATH + albm->getTheme()) )
492 {
493 presentationResourcesPath = THEMES_PATH + albm->getTheme() + "/misc_resources/";
494 }
495 //else try to load resources from the saved album path, this is necessary
496 //when viewing albums on machines that do not have the used theme installed
497 else
498 {
499 presentationResourcesPath = albm->getSaveLocation() + "/misc_resources/";
500 }
501
502 //load text border images
503 Top_TextBorder.load(presentationResourcesPath + "Top_TextBorder.png" );
504 Bottom_TextBorder.load(presentationResourcesPath + "Bottom_TextBorder.png" );
505 Left_TextBorder.load(presentationResourcesPath + "Left_TextBorder.png" );
506 Right_TextBorder.load(presentationResourcesPath + "Right_TextBorder.png" );
507 TL_TextBorder.load(presentationResourcesPath + "TL_TextBorder.png" );
508 TR_TextBorder.load(presentationResourcesPath + "TR_TextBorder.png" );
509 BL_TextBorder.load(presentationResourcesPath + "BL_TextBorder.png" );
510 BR_TextBorder.load(presentationResourcesPath + "BR_TextBorder.png" );
511
512 qApp->setOverrideCursor( QCursor(Qt::BlankCursor));
513 mouseShown = false;
514 setMouseTracking(true);
515/* showCoverPage();*/
516
517 //if collection and photo pointers are not null go immediately to specified collection/photo
518 if(startCollection != NULL && startPhoto != NULL)
519 {
520 //set photo and collection pointers
521 curPhoto = startPhoto;
522 curCollection = startCollection;
523
524 //set photo and collection count #'s
525 collectionNum = 1;
526 Subalbum* tmpCollection = albm->getFirstSubalbum();
527 while(tmpCollection != NULL && tmpCollection != curCollection)
528 {
529 tmpCollection = tmpCollection->getNext();
531 }
532 photoNum = 1;
533 Photo* tmpPhoto = curCollection->getFirst();
534 while(tmpPhoto != NULL && tmpPhoto!= curPhoto)
535 {
536 tmpPhoto = tmpPhoto->getNext();
537 photoNum++;
538 }
539
540 //load photo and display
541 loadPhoto();
543
544 //start auto-advance counter
545 if(autoPlay)
546 autoPlayTimer->start( (int)1000*autoPlayDelay, TRUE );
547 }
548 //otherwise show album cover page
549 else { showCoverPage(); }
550}
551//==============================================
553{
554 //for now just bring up first collection
555 collectionNum = 1;
557}
558//==============================================
560{
561 //set subalbum pointer
562 curCollection = subalbum;
563
564 //for now load up first photo
566 photoNum = 1;
567
568 loadPhoto();
570 if(autoPlay)
571 autoPlayTimer->start( (int)1000*autoPlayDelay, TRUE );
572}
573//==============================================
575{
576 if(autoPlay && autoPlayDelay > 1)
577 {
578 autoPlayTimer->stop();
582 autoPlayTimer->start( (int)1000*autoPlayDelay, TRUE );
583 }
584}
585//==============================================
587{
588 if(autoPlay && autoPlayDelay < 8)
589 {
590 autoPlayTimer->stop();
594 autoPlayTimer->start( (int)1000*autoPlayDelay, TRUE );
595 }
596}
597//==============================================
603//==============================================
609//==============================================
611{
612 //bail if currently animating
613 animatingMutex.lock();
614 if(animating)
615 {
616 animatingMutex.unlock();
617 return;
618 }
619
620 //stop autoPlay timer so next advance only occur after delay after advance is complete
621 autoPlayTimer->stop();
622
623 animating = true;
624 if(USE_ANIMATION)
626 else
627 type = IMMEDIATE;
628 animatingMutex.unlock();
629
630 if(curPhoto->getNext() == NULL)
631 { advanceCollection(); }
632 else
633 {
634 //load and display new photo
636 photoNum++;
637 loadPhoto();
639 }
640}
641//==============================================
643{
644 //bail if currently animating
645 animatingMutex.lock();
646 if(animating)
647 {
648 animatingMutex.unlock();
649 return;
650 }
651
652 animating = true;
653 if(USE_ANIMATION)
655 else
656 type = IMMEDIATE;
657 animatingMutex.unlock();
658
659 if(curPhoto->getPrev() == NULL)
660 { backupCollection(); }
661 else
662 {
663 //load and display new photo
665 photoNum--;
666 loadPhoto();
668}
669}
670//==============================================
672{
673 //bail if already at first photo in collection
675 return;
676
677 //bail if currently animating
678 animatingMutex.lock();
679 if(animating)
680 {
681 animatingMutex.unlock();
682 return;
683 }
684
685 animating = true;
686 if(USE_ANIMATION)
688 else
689 type = IMMEDIATE;
690 animatingMutex.unlock();
691
693 photoNum = 1;
694 //load and display new photo
695 loadPhoto();
697}
698//==============================================
700{
701 //bail if already at last photo in collection
703 return;
704
705 //bail if currently animating
706 animatingMutex.lock();
707 if(animating)
708 {
709 animatingMutex.unlock();
710 return;
711 }
712
713 animating = true;
714 if(USE_ANIMATION)
716 else
717 type = IMMEDIATE;
718 animatingMutex.unlock();
719
722
723 //load and display new photo
724 loadPhoto();
726}
727//==============================================
729{
730 if(USE_ANIMATION)
731 {
732 if(curCollection->getNext() == NULL &&
735 else
736 type = SCROLL_UP;
737 }
738 else
739 type = IMMEDIATE;
740
741 //keep advancing collections until we find one with a photo in it
742 curPhoto = NULL;
743 while(curPhoto == NULL)
744 {
747 if(!curCollection)
748 {
750 collectionNum = 1;
751 }
752
754 }
755 photoNum = 1;
756
757 //load and display new photo
758 loadPhoto();
760}
761//==============================================
763{
764 if(USE_ANIMATION)
765 {
766 if(curCollection->getPrev() == NULL &&
769 else
771 }
772 else
773 type = IMMEDIATE;
774
775 //keep backing up collections until we find one with a photo in it
776 curPhoto = NULL;
777 while(curPhoto == NULL)
778 {
781 if(!curCollection)
782 {
785 }
786
788 }
790
791 //load and display new photo
792 loadPhoto();
794}
795//==============================================
797{
798 //---------------------------------
799 //determine new number of columns to be shown
800
801 //determine # of ms that have passed since last redraw
802 currentTime.start();
803 double ms = lastTime.msecsTo(currentTime);
804
805 //determine increment
806 int inc = (int)(ms/delay);
807
808 //if increment is not zero then update last time
809 if(inc != 0)
810 {
812 }
813
814 //update number of columns shown
815 step+=inc;
816
817 //boundary conditions
818 if( step > screenWidth && (type == SCROLL_LEFT || type == SCROLL_RIGHT) )
820 if( step > screenHeight && (type == SCROLL_UP || type == SCROLL_DOWN) )
822
823 //if step changed then redraw
824 if(step != lastStep)
825 {
826 if(type == SCROLL_LEFT)
827 {
828 bitBlt( &screenBuffer, 0, 0,
830 step, 0,
831 paintBufferPrev->width() - step, paintBufferPrev->height(),
832 CopyROP, true );
833 bitBlt( &screenBuffer, paintBufferCurr->width() - step, 0,
835 0, 0, step, paintBufferCurr->height(),
836 CopyROP, true );
837 }
838 else if(type == SCROLL_RIGHT)
839 {
840 bitBlt( &screenBuffer, step, 0,
842 0, 0,
843 paintBufferPrev->width() - step, paintBufferPrev->height(),
844 CopyROP, true );
845 bitBlt( &screenBuffer, 0, 0,
847 paintBufferCurr->width() - step, 0, step, paintBufferCurr->height(),
848 CopyROP, true );
849 }
850 else if(type == SCROLL_UP)
851 {
852 bitBlt( &screenBuffer, 0, 0,
854 0, step,
855 paintBufferPrev->width(), paintBufferPrev->height() - step,
856 CopyROP, true );
857 bitBlt( &screenBuffer, 0, paintBufferCurr->height() - step,
859 0, 0, paintBufferCurr->width(), step,
860 CopyROP, true );
861 }
862 else if(type == SCROLL_DOWN)
863 {
864 bitBlt( &screenBuffer, 0, step,
866 0, 0,
867 paintBufferPrev->width(), paintBufferPrev->height() - step,
868 CopyROP, true );
869 bitBlt( &screenBuffer, 0, 0,
871 0, paintBufferCurr->height() - step, paintBufferCurr->width(), step,
872 CopyROP, true );
873 }
874
875 //paint overlaid controls
877
878 //blit to screen
879 repaint(false);
880
881 lastStep = step;
882
883 //not done animating, reiterate
884 if(
885 (
886 step < screenWidth &&
888 ) ||
889 (
890 step < screenHeight &&
891 (type == SCROLL_UP || type == SCROLL_DOWN)
892 )
893 )
894 {
895 //update speed
896 delay = delay * accel;
897 if(delay < minDelay) delay = minDelay ;
898
899 //restart timer
900 animatingTimer->start( (int)delay, TRUE );
901 }
902 //done animating....
903 else
904 {
905 animating = false;
906
907 //if using debug messages use refreshScreen method which actually displays these.
908 //such messages are laid on time and thus not shown when transitioning
910 refreshScreen();
911
912 //if autoplay is enabled restart timer
913 if(autoPlay)
914 autoPlayTimer->start( (int)1000*autoPlayDelay, TRUE );
915 }
916 }
917 else
918 {
919 //update speed
920 delay = delay * accel;
922
923 //restart timer
924 animatingTimer->start( (int)delay, TRUE );
925 }
926 //---------------------------------------
927}
928//==============================================
930{
931 //if transition is set to immediate then just show new photo
932 if(type == IMMEDIATE)
933 {
935 animating = false;
936 return;
937 }
938
939 //setup step counter
940 lastStep = 0;
941 step = 0;
942
943 //set initial delay/speed
945
946 //exchange buffers
947 QPixmap* temp = paintBufferCurr;
949 paintBufferPrev = temp;
950
951 //paint new image to curr buffer
952 showPhoto();
953
954 //find current time, used to decide how many new columns to reveal in first iteration
955 lastTime.start();
956
957 //begin animation
958 animate();
959}
960//==============================================
962{
963 //paint current photo to paintBufferCurr
964 showPhoto();
965
966 //blit to screen buffer
967 bitBlt( &screenBuffer, 0, 0,
969 0, 0, paintBufferCurr->width(), paintBufferCurr->height(),
970 CopyROP, true );
971
972 //paint overlaid controls
974}
975//==============================================
977{
978 QString tempString = "";
979 int x, y;
980
981 //setup painter to screen buffer for laying on top all top level widgets
982 QPainter p;
983 p.begin( &screenBuffer );
984 //------------------------------
985 //setup font stuff for writing text
986 QFont f( "times", fontSize, QFont::Bold );
987 QFontMetrics fm( f );
988 p.setFont( f );
989 //------------------------------
990 //paint autoPlay delay
992 {
993 //get handle on right speed icon
994 QImage* speedIcon;
995 if(autoPlayDelay == 1) speedIcon = &speed1;
996 else if(autoPlayDelay == 2) speedIcon = &speed2;
997 else if(autoPlayDelay == 4) speedIcon = &speed4;
998 else speedIcon = &speed8;
999
1000 int maxWidth = speed1.width();
1001 if(speed2.width() > maxWidth) maxWidth = speed2.width();
1002 if(speed4.width() > maxWidth) maxWidth = speed4.width();
1003 if(speed8.width() > maxWidth) maxWidth = speed8.width();
1004
1005 int maxHeight = speed1.height();
1006 if(speed2.height() > maxHeight) maxHeight = speed2.height();
1007 if(speed4.height() > maxHeight) maxHeight = speed4.height();
1008 if(speed8.height() > maxHeight) maxHeight = speed8.height();
1009
1010 x = screenWidth - TEXT_MARGIN - speedIcon->width() - (maxWidth - speedIcon->width())/2;
1011 y = screenHeight - TEXT_MARGIN - speedIcon->height() - (maxHeight - speedIcon->height())/2;
1012
1013 p.drawImage( x, y, *speedIcon );
1014 displayAutoPlayDelay = false;
1015 }
1016 //------------------------------
1017 //if debugging enabled paint such messages
1019 {
1020 //before debugging message set color to green
1021 p.setPen(QColor("green"));
1022 //------------------------------
1023 //paint collection number
1024 tempString = QString("(Collection %1 / %2)").arg(collectionNum).arg(curAlbum->getNumSubalbums());
1025 x = 0;
1026 y = 0;
1027 p.fillRect( x, y, fm.width(tempString), fm.height(), QBrush(QColor("black")) );
1028 p.drawText( x, y + fm.ascent(), tempString );
1029 //------------------------------
1030 //paint photo number
1031 tempString = QString("(Photo %1 / %2)").arg(photoNum).arg(curCollection->getNumPhotos());
1032 x = screenWidth - fm.width(tempString);
1033 y = 0;
1034 p.fillRect( x, y, fm.width(tempString), fm.height(), QBrush(QColor("black")) );
1035 p.drawText(x, y + fm.ascent(), tempString );
1036 }
1037 //------------------------------
1038 //if the mouse is shown paint the control interface
1039 if(mouseShown)
1040 {
1041 QImage* shownInterface;
1042 if(autoPlay)
1043 shownInterface = &pauseInterface;
1044 else
1045 shownInterface = &playInterface;
1046
1047 x = ( screenWidth - shownInterface->width() ) / 2;
1048 y = screenHeight - shownInterface->height() - TEXT_MARGIN;
1049 p.drawImage( x, y, *shownInterface );
1050
1051 //paint collection # and photo #
1052 f.setPointSize( 14 );
1053 fm = QFontMetrics( f );
1054 tempString = QString("%1 / %2").arg(photoNum).arg(curCollection->getNumPhotos());
1055 x = x + (shownInterface->width() / 2) - (fm.width(tempString) / 2);
1056 y = y + 104;
1057 p.setFont( f );
1058 p.setPen(QColor("white"));
1059 p.drawText( x, y, tempString );
1060 }
1061 //------------------------------
1062 //ender painter and flast to screen
1063 p.end();
1064 repaint(false);
1065}
1066//==============================================
1068//==============================================
1070//==============================================
1071
An album contains Subalbums.
Definition album.h:53
Subalbum * getFirstSubalbum()
Returns a pointer to the first Subalbum.
Definition album.cpp:135
int getNumSubalbums()
Returns number of subalbums.
Definition album.cpp:144
QString getTheme()
Returns currently selected theme.
Definition album.cpp:143
QString getSaveLocation()
Returns the current save location of all images.
Definition album.cpp:141
Subalbum * getLastSubalbum()
Returns a pointer to the last Subalbum.
Definition album.cpp:136
A photo consists of a full size image, a smaller slide show image, a very small thumbnail image,...
Definition photo.h:45
Photo * getNext()
Returns next photo pointer.
Definition photo.cpp:225
QString getImageFilename()
Gets the image filename.
Definition photo.cpp:192
Photo * getPrev()
Returns the previous photo pointer.
Definition photo.cpp:224
QString getDescription()
Gets the description.
Definition photo.cpp:208
SlideshowWidget(QWidget *parent=0, const char *name=0, WFlags f=0)
void mousePressEvent(QMouseEvent *e)
void beginSlideshow(Album *albm, Subalbum *startCollection=NULL, Photo *startPhoto=NULL)
Subalbum * getCurCollection()
returns a pointer to the currently visible collection
void contextMenuEvent(QContextMenuEvent *e)
Photo * getCurPhoto()
returns a pointer to the currently visible photo
void paintEvent(QPaintEvent *)
void keyPressEvent(QKeyEvent *e)
void mouseMoveEvent(QMouseEvent *e)
ANIMATION_TYPE type
void showCollectionPage(Subalbum *subalbum)
A subalbum contains photos.
Definition subalbum.h:49
Subalbum * getPrev()
Returns pointer to prev subalbum.
Definition subalbum.cpp:97
int getNumPhotos()
Returns the number of photos in the subalbum.
Definition subalbum.cpp:104
Photo * getLast()
Returns last photo in subalbum.
Definition subalbum.cpp:101
Subalbum * getNext()
Returns pointer to next subalbum.
Definition subalbum.cpp:98
Photo * getFirst()
Returns first photo in subalbum.
Definition subalbum.cpp:100
QString IMAGE_PATH
Definition config.cpp:18
QString THEMES_PATH
Definition config.cpp:21
bool scaleImage(QString fileIn, QString fileOut, int newWidth, int newHeight)
Scale image and save copy to disk.
#define USE_ANIMATION
#define TEXT_MARGIN
#define HIDE_MOUSE_DELAY
@ SCROLL_LEFT
@ IMMEDIATE
@ SCROLL_DOWN
@ SCROLL_RIGHT
@ SCROLL_UP