ginebra2/linearflowsnippet.cpp
changeset 0 1450b09d0cfd
child 3 0954f5dd2cd0
child 5 0f2326c2a325
equal deleted inserted replaced
-1:000000000000 0:1450b09d0cfd
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 #include <QDebug>
       
    19 #include <QImage>
       
    20 #include <QPainter>
       
    21 #include <QResizeEvent>
       
    22 #include <QTimeLine>
       
    23 #include <QGraphicsSceneResizeEvent>
       
    24 #include <QGraphicsSceneMouseEvent>
       
    25 #include <QGraphicsSceneMoveEvent>
       
    26 #include <QGraphicsDropShadowEffect>
       
    27 #include "linearflowsnippet.h"
       
    28 
       
    29 #define SAFE_DELETE(p) if(p) delete p;
       
    30 
       
    31 #define SNIPPET_AUTOHIDE_TIMEOUT 5000 //5secs
       
    32 
       
    33 #define CALL_ON_PREV_PREV_FILM_STRIP(func) if (d->m_centerIndex - 2 >= 0) d->m_films[d->m_centerIndex - 2]->func; else if(d->m_centerIndex == 1) d->m_films[d->m_films.size() - 1]->func; else d->m_films[d->m_films.size() - 2]->func;
       
    34 #define CALL_ON_CENTER_FILM_STRIP(func) if (d->m_centerIndex >= 0 && d->m_centerIndex < d->m_films.size()) d->m_films[d->m_centerIndex]->func; else if(d->m_centerIndex < 0) d->m_films[d->m_films.size() + d->m_centerIndex]->func; else d->m_films[(d->m_centerIndex)%d->m_films.size()]->func; 
       
    35 #define CALL_ON_PREV_PREV_PREV_FILM_STRIP(func) if (d->m_centerIndex - 3 >= 0) d->m_films[d->m_centerIndex - 3]->func; else if(d->m_centerIndex == 1) d->m_films[d->m_films.size() - 2]->func; else if(d->m_centerIndex == 2) d->m_films[d->m_films.size() - 1]->func; else d->m_films[d->m_films.size() - 3]->func;
       
    36 #define CALL_ON_NEXT_NEXT_NEXT_FILM_STRIP(func) if (d->m_centerIndex + 3 < d->m_films.size()) d->m_films[d->m_centerIndex + 3]->func; else d->m_films[(d->m_centerIndex + 3)%d->m_films.size()]->func; 
       
    37 #define CALL_ON_NEXT_NEXT_FILM_STRIP(func) if (d->m_centerIndex + 2 < d->m_films.size()) d->m_films[d->m_centerIndex + 2]->func; else d->m_films[(d->m_centerIndex + 2)%d->m_films.size()]->func; 
       
    38 #define CALL_ON_PREV_FILM_STRIP(func) if (d->m_centerIndex - 1 >= 0) d->m_films[d->m_centerIndex - 1]->func; else d->m_films[d->m_films.size() - 1]->func;
       
    39 #define CALL_ON_NEXT_FILM_STRIP(func) if (d->m_centerIndex + 1 < d->m_films.size()) d->m_films[d->m_centerIndex + 1]->func; else d->m_films[(d->m_centerIndex + 1)%d->m_films.size()]->func; 
       
    40 
       
    41 
       
    42 #define INVALID_INDEX -1
       
    43 
       
    44 #define L_CENTER_WIDTH_P_C 0.27
       
    45 #define L_CENTER_HEIGHT_P_C 0.70
       
    46 #define L_SIDE_WIDTH_P_C 0.27
       
    47 #define L_SIDE_HEIGHT_P_C 0.70
       
    48 
       
    49 #define L_CENTER_TOP_SPACE_P_C 0.15
       
    50 #define L_SIDE_TOP_SPACE_P_C 0.15
       
    51 
       
    52 #define L_SPACE_P_C 0.05
       
    53 
       
    54 #define SPACE_P_C 0.11
       
    55 #define CLOSE_ICON_ADJUST_SIZE 5
       
    56 #define TITLE_SPACE 10
       
    57 #define FRAME_WIDTH 4
       
    58 
       
    59 #define ANIMATION_DURATION 300
       
    60 #define ANIMATION_MAX_FRAME 20.0
       
    61 #define NEW_FILM_TITLE ""
       
    62 
       
    63 #define WIDTH 360
       
    64 #define TITLE_HEIGHT 0.15
       
    65 #define FILM_HEIGHT 0.85
       
    66 #define P_MAX_SLIDE 3
       
    67 #define L_MAX_SLIDE 5
       
    68 #define MAX_FLICK_SPEED 500
       
    69 #define THRESHOLD_FLICK_SPEED 400
       
    70 #define THRESHOLD_FLICK_TIME 75
       
    71 
       
    72 namespace GVA {
       
    73 
       
    74 // movies (animation) name
       
    75 const QString BreakinLeft   = "bil";//"breakin - left";
       
    76 const QString BreakinRight  = "bir";//"breakin - right";
       
    77 const QString BreakoutLeft  = "bol";//"breakout - left";
       
    78 const QString BreakoutRight = "bor";//"breakout - right";
       
    79 
       
    80 const QString BreakinLeftLeft = "bill";//"breakin - leftleft"
       
    81 const QString BreakinRightRight = "birr";//"breakin - rightright"
       
    82 const QString BreakoutLeftLeft = "boll";//"breakout - leftleft"
       
    83 const QString BreakoutRightRight = "borr";//"breakout rightright"
       
    84 
       
    85 const QString RightToCenter = "rc";//"right - center";
       
    86 const QString LeftToCenter  = "lc";//"left - center";
       
    87 const QString CenterToRight = "cr";//"center - right";
       
    88 const QString CenterToLeft  = "cl";//"center - left";
       
    89 
       
    90 const QString LeftLeftToLeft = "lltl"; //"leftLft - left"
       
    91 const QString LeftToLeftLeft = "ltll";//left - leftleft"
       
    92 const QString RightToRightRight = "rtrr";//"right - rightright"
       
    93 const QString RightRightToRight = "rrtr";//"rightright - right"
       
    94 
       
    95 const QString FadeOut       = "fo";//"fadeout";
       
    96 const QString ZoomIn        = "zi";//"zoomin";
       
    97 const QString ZoomOut       = "zo";//"zoomto";
       
    98 // -------------------------------------------------------
       
    99 // Help functions
       
   100 
       
   101 //static QImage* createFilmstrip(const QImage& img, QSize
       
   102 
       
   103 // -------------------------------------------------------
       
   104 // Help classes
       
   105 class FilmstripMovieFactory;
       
   106 
       
   107 class FilmstripMovie
       
   108 {
       
   109 friend class FilmstripMovieFactory;
       
   110 
       
   111 public:
       
   112 
       
   113 enum MovieType
       
   114 {
       
   115 FADE_IN,
       
   116 FADE_OUT,
       
   117 TRANSLATE
       
   118 };
       
   119 
       
   120 public:
       
   121     FilmstripMovie(const QString& name) { m_name = name; m_movieType = TRANSLATE;}
       
   122     ~FilmstripMovie() {m_movieClips.clear();}
       
   123     QRectF& movieClip(int frame);
       
   124 
       
   125 public:
       
   126     MovieType m_movieType;
       
   127 
       
   128 private:
       
   129     QString m_name;
       
   130     QList<QRectF> m_movieClips;
       
   131 };
       
   132 
       
   133 class FilmstripMovieFactory
       
   134 {
       
   135 public:
       
   136     FilmstripMovieFactory(FilmstripFlowPrivate* filmstripFlowData = NULL): m_filmstripFlowData(filmstripFlowData) {}
       
   137     ~FilmstripMovieFactory();
       
   138 
       
   139     FilmstripMovie* createMovie(const QString& name);
       
   140 
       
   141     void updateAllMovie();
       
   142     void setFilmstripFlowData(FilmstripFlowPrivate* filmstripFlowData) { m_filmstripFlowData = filmstripFlowData; }
       
   143 
       
   144 protected:
       
   145     void addRectByFrame(FilmstripMovie* movie, QRectF& startRect, QRectF& endRect, qreal x1, qreal y1, qreal x2, qreal y2, bool debug = false);
       
   146     void createRightOutMovie(FilmstripMovie* movie);
       
   147     void createRightInMovie(FilmstripMovie* movie);
       
   148     void createLeftInMovie(FilmstripMovie* movie);
       
   149     void createLeftOutMovie(FilmstripMovie* movie);
       
   150     void createRightToCenterMovie(FilmstripMovie* movie);
       
   151     void createLeftToCenterMovie(FilmstripMovie* movie);
       
   152     void createCenterToLeftMovie(FilmstripMovie* movie);
       
   153     void createCenterToRightMovie(FilmstripMovie* movie);
       
   154     void createFadeOutMovie(FilmstripMovie* movie);
       
   155     void createZoomInMovie(FilmstripMovie* movie);
       
   156     void createZoomOutMovie(FilmstripMovie* movie);
       
   157     void createLeftLeftInMovie(FilmstripMovie* movie);
       
   158     void createRightRightInMovie(FilmstripMovie* movie);
       
   159     void createLeftLeftOutMovie(FilmstripMovie* movie);
       
   160     void createRightRightOutMovie(FilmstripMovie* movie);
       
   161     void createLeftLeftToLeftMovie(FilmstripMovie* movie);
       
   162     void createLeftToLeftLeftMovie(FilmstripMovie* movie);
       
   163     void createRightToRightRightMovie(FilmstripMovie* movie);
       
   164     void createRightRightToRightMovie(FilmstripMovie* movie);
       
   165 
       
   166 private:
       
   167     FilmstripFlowPrivate* m_filmstripFlowData;
       
   168     QHash<QString, FilmstripMovie*> m_moviesCache;
       
   169 };
       
   170 
       
   171 class Filmstrip
       
   172 {
       
   173 public:
       
   174     Filmstrip(const QImage& img, FilmstripFlowPrivate* filmstripFlowData): m_img(img), m_frozen(false), m_movieFrame(0), m_movie(NULL), m_filmstripFlowData(filmstripFlowData) {}
       
   175     ~Filmstrip() {}
       
   176 
       
   177     void paint(QPainter* painter);
       
   178     void paintName(QPainter* painter);
       
   179 
       
   180     void freeze() {m_frozen = true;}
       
   181     void updateMovie(FilmstripMovie* movie) {m_movie = movie; m_movieFrame = 0; m_frozen = false;}
       
   182     void updateMovieFrame(int frame) { if(!m_frozen) m_movieFrame = frame;}
       
   183     void setName(const QString& name) {m_name = name;}
       
   184     QImage& image() {return m_img;}
       
   185     QString& name() {return m_name;}
       
   186 private:
       
   187     void createEmptyImage();
       
   188 
       
   189 public:
       
   190     QImage m_img;
       
   191     bool m_frozen;
       
   192     int m_movieFrame;
       
   193     QString m_name;
       
   194     FilmstripMovie* m_movie;
       
   195     FilmstripFlowPrivate* m_filmstripFlowData;
       
   196 };
       
   197 
       
   198 class FilmstripFlowPrivate
       
   199 {
       
   200 public:
       
   201     FilmstripFlowPrivate(): m_bgColor(QColor(99,105,115).rgb()), m_buffer(NULL), m_titleBuffer(NULL),m_closeIcon(NULL), m_centerTopSpace(0), m_sideTopSpace(0), m_space(0), m_incIndex(0), m_centerIndex(INVALID_INDEX) {}
       
   202 
       
   203     ~FilmstripFlowPrivate() {
       
   204         for (int i = 0; i < m_films.size(); i++)
       
   205             SAFE_DELETE(m_films[i]);
       
   206         m_films.clear();
       
   207         SAFE_DELETE(m_buffer);
       
   208         SAFE_DELETE(m_titleBuffer);
       
   209         SAFE_DELETE(m_closeIcon);
       
   210     }
       
   211 
       
   212     void clear() {
       
   213         m_centerIndex = INVALID_INDEX;
       
   214         for (int i = 0; i < m_films.size(); i++)
       
   215             SAFE_DELETE(m_films[i]);
       
   216         m_films.clear();
       
   217     }
       
   218 
       
   219 public:
       
   220     QRgb m_bgColor;
       
   221     QImage* m_buffer;
       
   222     QImage *m_titleBuffer;
       
   223     QImage* m_closeIcon;
       
   224     QList<Filmstrip*> m_films;
       
   225     QSize m_centerWindowSize;
       
   226     QSize m_sideWindowSize;
       
   227     QSize m_widgetSize;
       
   228     qreal m_centerTopSpace;
       
   229     qreal m_sideTopSpace;
       
   230     qreal m_space;
       
   231     QTimeLine m_movieTimer;
       
   232     FilmstripMovieFactory m_movieFactory;
       
   233     QPoint m_closeIconPos;
       
   234     QPoint m_lastMoveEventPos;
       
   235     int m_incIndex;
       
   236     int m_centerIndex;
       
   237 };
       
   238 
       
   239 // -------------------------------------------------------
       
   240 // Filmstrip
       
   241 void Filmstrip::createEmptyImage()
       
   242 {
       
   243     QRectF target = m_movie->movieClip(0);
       
   244     int w = target.width();
       
   245     int h = target.height();
       
   246     m_name = NEW_FILM_TITLE;
       
   247     m_img = QImage(w, h, QImage::Format_RGB32);
       
   248 
       
   249     QPainter painter(&m_img);
       
   250     painter.fillRect(0, 0, w, h, Qt::white);
       
   251     painter.end();
       
   252 }
       
   253 
       
   254 void Filmstrip::paint(QPainter* painter)
       
   255 {
       
   256     Q_ASSERT(painter);
       
   257 
       
   258     if (!m_movie)
       
   259         return;
       
   260     
       
   261     QRectF target;
       
   262 
       
   263     bool needFade = (m_movie->m_movieType == FilmstripMovie::FADE_OUT);
       
   264     if (needFade) // FIXME: no fade out support now
       
   265         target = m_movie->movieClip(0);
       
   266     else
       
   267         target = m_movie->movieClip(m_movieFrame);
       
   268     
       
   269     if(target.right() > 0 || target.left() < m_filmstripFlowData->m_widgetSize.width()) {
       
   270         if (needFade)
       
   271             painter->setOpacity((ANIMATION_MAX_FRAME - m_movieFrame) / ANIMATION_MAX_FRAME);
       
   272 
       
   273         painter->fillRect(target.adjusted(-FRAME_WIDTH,-FRAME_WIDTH,FRAME_WIDTH,FRAME_WIDTH), QColor(Qt::gray));
       
   274         
       
   275         if(!m_img.isNull())
       
   276             painter->drawImage(target, m_img);
       
   277     
       
   278         else {
       
   279             painter->save();
       
   280             painter->setPen(QColor(Qt::black));
       
   281             painter->setFont(QFont("Arial", 4));
       
   282             painter->drawText(target, Qt::AlignVCenter,m_name);
       
   283             painter->restore();
       
   284         }
       
   285 
       
   286         if (needFade) 
       
   287             painter->setOpacity(1); // restore opacity 
       
   288     }
       
   289 }
       
   290 
       
   291 void Filmstrip::paintName(QPainter* painter)
       
   292 {
       
   293     Q_ASSERT(painter);
       
   294     if (!m_name.isEmpty()) {
       
   295         QPoint startPoint;
       
   296         QString name = m_name;
       
   297         QFontMetrics fm = painter->fontMetrics();
       
   298         int pixelWidth = fm.width(name);
       
   299         int filmstripWidth = m_filmstripFlowData->m_centerWindowSize.width();
       
   300         if (pixelWidth > filmstripWidth) {
       
   301             qreal letterWidth = pixelWidth / (qreal)name.size();
       
   302             name = name.leftJustified(filmstripWidth / letterWidth - 3, '.', true) + "...";
       
   303             startPoint = QPoint((m_filmstripFlowData->m_widgetSize.width() - filmstripWidth) /2, m_filmstripFlowData->m_centerTopSpace - TITLE_SPACE);
       
   304         }
       
   305         else
       
   306             startPoint = QPoint((m_filmstripFlowData->m_widgetSize.width() - pixelWidth) /2, m_filmstripFlowData->m_centerTopSpace - TITLE_SPACE);
       
   307 
       
   308         painter->save();
       
   309         painter->setPen(QColor(Qt::black));
       
   310         painter->drawText(startPoint, name);
       
   311         painter->restore();
       
   312     }
       
   313 }
       
   314 
       
   315 // -------------------------------------------------------
       
   316 // FilmstripMovie
       
   317 QRectF& FilmstripMovie::movieClip(int frame)
       
   318 {
       
   319     Q_ASSERT(frame >= 0 && frame < m_movieClips.size());
       
   320     return m_movieClips[frame];
       
   321 }
       
   322 
       
   323 // -------------------------------------------------------
       
   324 // FilmstripMovieFactory
       
   325 FilmstripMovieFactory::~FilmstripMovieFactory() 
       
   326 {
       
   327     QHashIterator<QString, FilmstripMovie*> i(m_moviesCache);
       
   328     while (i.hasNext()) {
       
   329         i.next();
       
   330         delete i.value();
       
   331     }
       
   332     m_moviesCache.clear();
       
   333 }
       
   334 
       
   335 FilmstripMovie* FilmstripMovieFactory::createMovie(const QString& name)
       
   336 {
       
   337     FilmstripMovie* movie = NULL;
       
   338     QHash<QString, FilmstripMovie*>::const_iterator i = m_moviesCache.find(name);
       
   339     if (i == m_moviesCache.end()) {
       
   340         //qDebug() << "create a new movie: " << name;
       
   341         movie = new FilmstripMovie(name);
       
   342 
       
   343         if (name == BreakoutRight)
       
   344             createRightOutMovie(movie);
       
   345         else if (name == BreakoutLeft)
       
   346             createLeftOutMovie(movie);
       
   347         else if (name == BreakinLeft)
       
   348             createLeftInMovie(movie);
       
   349         else if (name == BreakinRight)
       
   350             createRightInMovie(movie);
       
   351         else if (name == CenterToRight)
       
   352             createCenterToRightMovie(movie);
       
   353         else if (name == CenterToLeft)
       
   354             createCenterToLeftMovie(movie);
       
   355         else if (name == RightToCenter)
       
   356             createRightToCenterMovie(movie);
       
   357         else if (name == LeftToCenter)
       
   358             createLeftToCenterMovie(movie);
       
   359         else if (name == FadeOut)
       
   360             createFadeOutMovie(movie);
       
   361         else if (name == ZoomIn)
       
   362             createZoomInMovie(movie);
       
   363         else if (name == ZoomOut)
       
   364             createZoomOutMovie(movie);
       
   365         else if (name == BreakinLeftLeft)
       
   366             createLeftLeftInMovie(movie);
       
   367         else if (name == BreakinRightRight)
       
   368             createRightRightInMovie(movie);
       
   369         else if (name == BreakoutLeftLeft)
       
   370             createLeftLeftOutMovie(movie);
       
   371         else if (name == BreakoutRightRight)    
       
   372             createRightRightOutMovie(movie);
       
   373         else if (name == LeftLeftToLeft)
       
   374             createLeftLeftToLeftMovie(movie);
       
   375         else if (name == LeftToLeftLeft)
       
   376             createLeftToLeftLeftMovie(movie);
       
   377         else if (name == RightToRightRight)
       
   378             createRightToRightRightMovie(movie);
       
   379         else if(name == RightRightToRight)
       
   380             createRightRightToRightMovie(movie);
       
   381 
       
   382         m_moviesCache[name] = movie;
       
   383     } else {
       
   384         movie =  m_moviesCache.value(name);
       
   385     }
       
   386     return movie;
       
   387 }
       
   388 
       
   389 void FilmstripMovieFactory::createLeftLeftInMovie(FilmstripMovie* movie) 
       
   390 {
       
   391     movie->m_movieClips.clear();
       
   392     int cw = m_filmstripFlowData->m_centerWindowSize.width();
       
   393     int sw = m_filmstripFlowData->m_sideWindowSize.width();
       
   394     int sh = m_filmstripFlowData->m_sideWindowSize.height();
       
   395     int w = m_filmstripFlowData->m_widgetSize.width();
       
   396     int h = m_filmstripFlowData->m_widgetSize.height();
       
   397 
       
   398     qreal cx = ((w - 4 * m_filmstripFlowData->m_space) - cw) / 2.0 - sw + m_filmstripFlowData->m_space; 
       
   399     qreal sx = ((w - 4 * m_filmstripFlowData->m_space) - cw) / 2.0 - 2 * sw; 
       
   400     qreal sy = m_filmstripFlowData->m_sideTopSpace;
       
   401     qreal stepx = (cx - sx) / ANIMATION_MAX_FRAME;
       
   402 
       
   403     QRectF startRect = QRectF( 2 *  sx - cx , sy, sw, sh);
       
   404     QRectF endRect = QRectF(sx, sy, sw, sh);
       
   405 
       
   406     addRectByFrame(movie, startRect, endRect, stepx, 0, stepx, 0);
       
   407 }
       
   408 
       
   409 void FilmstripMovieFactory::createRightRightInMovie(FilmstripMovie* movie)
       
   410 {
       
   411     movie->m_movieClips.clear();
       
   412     int cw = m_filmstripFlowData->m_centerWindowSize.width();
       
   413     int sw = m_filmstripFlowData->m_sideWindowSize.width();
       
   414     int sh = m_filmstripFlowData->m_sideWindowSize.height();
       
   415     int w = m_filmstripFlowData->m_widgetSize.width();
       
   416     int h = m_filmstripFlowData->m_widgetSize.height();
       
   417 
       
   418     qreal cx = (w + 4 * m_filmstripFlowData->m_space + cw) / 2.0 - m_filmstripFlowData->m_space;
       
   419     qreal sx = ((w + 4 * m_filmstripFlowData->m_space + cw) / 2.0) + sw ; 
       
   420     qreal sy = m_filmstripFlowData->m_sideTopSpace;
       
   421     qreal stepx = (cx - sx) / ANIMATION_MAX_FRAME;
       
   422 
       
   423     QRectF startRect = QRectF(2 * sx - cx, sy, sw, sh);
       
   424     QRectF endRect = QRectF(sx , sy, sw, sh);
       
   425 
       
   426     addRectByFrame(movie, startRect, endRect, stepx, 0, stepx, 0);
       
   427 }
       
   428 
       
   429 void FilmstripMovieFactory::createLeftLeftOutMovie(FilmstripMovie* movie)
       
   430 {
       
   431     movie->m_movieClips.clear();
       
   432     int cw = m_filmstripFlowData->m_centerWindowSize.width();
       
   433     int sw = m_filmstripFlowData->m_sideWindowSize.width();
       
   434     int sh = m_filmstripFlowData->m_sideWindowSize.height();
       
   435     int w = m_filmstripFlowData->m_widgetSize.width();
       
   436     int h = m_filmstripFlowData->m_widgetSize.height();
       
   437 
       
   438     qreal cx = ((w - 4 * m_filmstripFlowData->m_space) - cw) / 2.0 - sw + m_filmstripFlowData->m_space; 
       
   439     qreal sx = (((w - 4 * m_filmstripFlowData->m_space) - cw) / 2.0) - (2 *sw); 
       
   440     qreal sy = m_filmstripFlowData->m_sideTopSpace;
       
   441     qreal stepx = (sx -cx) / ANIMATION_MAX_FRAME;
       
   442 
       
   443     QRectF startRect = QRectF(sx, sy, sw, sh);
       
   444     QRectF endRect = QRectF(2 * sx - cx , sy, sw, sh);
       
   445 
       
   446     addRectByFrame(movie, startRect, endRect, stepx, 0, stepx, 0);
       
   447 }
       
   448 
       
   449 void FilmstripMovieFactory::createRightRightOutMovie(FilmstripMovie* movie)
       
   450 {
       
   451     movie->m_movieClips.clear();
       
   452     int cw = m_filmstripFlowData->m_centerWindowSize.width();
       
   453     int sw = m_filmstripFlowData->m_sideWindowSize.width();
       
   454     int sh = m_filmstripFlowData->m_sideWindowSize.height();
       
   455     int w = m_filmstripFlowData->m_widgetSize.width();
       
   456     int h = m_filmstripFlowData->m_widgetSize.height();
       
   457 
       
   458     qreal cx = (w + 4 * m_filmstripFlowData->m_space + cw) / 2.0 - m_filmstripFlowData->m_space;
       
   459     qreal sx = ((w + 4 * m_filmstripFlowData->m_space + cw) / 2.0) + sw ; 
       
   460     qreal sy = m_filmstripFlowData->m_sideTopSpace;
       
   461     qreal stepx = (sx - cx) / ANIMATION_MAX_FRAME;
       
   462 
       
   463     QRectF startRect = QRectF(sx, sy, sw, sh);
       
   464     QRectF endRect = QRectF(2 * sx - cx, sy, sw, sh);
       
   465     addRectByFrame(movie, startRect, endRect, stepx, 0, stepx, 0);
       
   466 }
       
   467 
       
   468 void FilmstripMovieFactory::createLeftLeftToLeftMovie(FilmstripMovie* movie)
       
   469 {
       
   470     movie->m_movieClips.clear();
       
   471     int cw = m_filmstripFlowData->m_centerWindowSize.width();
       
   472     int ch = m_filmstripFlowData->m_centerWindowSize.height();
       
   473     int sw = m_filmstripFlowData->m_sideWindowSize.width();
       
   474     int sh = m_filmstripFlowData->m_sideWindowSize.height();
       
   475     int w = m_filmstripFlowData->m_widgetSize.width();
       
   476     int h = m_filmstripFlowData->m_widgetSize.height();
       
   477 
       
   478     qreal step = ANIMATION_MAX_FRAME;
       
   479     qreal cx = ((w - 4 * m_filmstripFlowData->m_space) - cw) / 2.0 - sw + m_filmstripFlowData->m_space; 
       
   480     qreal cy = m_filmstripFlowData->m_centerTopSpace;
       
   481     qreal sx = (((w - 4 * m_filmstripFlowData->m_space) - cw) / 2.0) - (2 *sw); 
       
   482     qreal sy = m_filmstripFlowData->m_sideTopSpace;
       
   483     qreal stepx = (cx - sx) / step;
       
   484     qreal stepy = (cy - sy) / step;
       
   485     qreal stepx2 = stepx + (cw - sw) / step;
       
   486     qreal stepy2 = stepy + (ch - sh) / step;
       
   487  
       
   488     QRectF startRect = QRectF(sx, sy, sw, sh);
       
   489     QRectF endRect = QRectF(cx, cy, cw, ch);
       
   490 
       
   491     addRectByFrame(movie, startRect, endRect, stepx, stepy, stepx2, stepy2);
       
   492 }
       
   493 
       
   494 void FilmstripMovieFactory::createLeftToLeftLeftMovie(FilmstripMovie* movie)
       
   495 {
       
   496     movie->m_movieClips.clear();
       
   497     int cw = m_filmstripFlowData->m_centerWindowSize.width();
       
   498     int ch = m_filmstripFlowData->m_centerWindowSize.height();
       
   499     int sw = m_filmstripFlowData->m_sideWindowSize.width();
       
   500     int sh = m_filmstripFlowData->m_sideWindowSize.height();
       
   501     int w = m_filmstripFlowData->m_widgetSize.width();
       
   502     int h = m_filmstripFlowData->m_widgetSize.height();
       
   503 
       
   504     qreal step = ANIMATION_MAX_FRAME;
       
   505     qreal cx = ((w - 4 * m_filmstripFlowData->m_space) - cw) / 2.0 - sw + m_filmstripFlowData->m_space; 
       
   506     qreal cy = m_filmstripFlowData->m_centerTopSpace;
       
   507     qreal sx = (((w - 4 * m_filmstripFlowData->m_space) - cw) / 2.0) - (2 *sw); 
       
   508     qreal sy = m_filmstripFlowData->m_sideTopSpace;
       
   509     qreal stepx = (sx - cx) / step;
       
   510     qreal stepy = (sy - cy) / step;
       
   511     qreal stepx2 = stepx + (sw - cw) / step;
       
   512     qreal stepy2 = stepy + (sh - ch) / step;
       
   513  
       
   514     QRectF startRect = QRectF(cx, cy, cw, ch);
       
   515     QRectF endRect = QRectF(sx, sy, sw, sh);
       
   516     addRectByFrame(movie, startRect, endRect, stepx, stepy, stepx2, stepy2);
       
   517 }
       
   518 
       
   519 void FilmstripMovieFactory::createRightToRightRightMovie(FilmstripMovie* movie)
       
   520 {
       
   521     movie->m_movieClips.clear();
       
   522     int cw = m_filmstripFlowData->m_centerWindowSize.width();
       
   523     int ch = m_filmstripFlowData->m_centerWindowSize.height();
       
   524     int sw = m_filmstripFlowData->m_sideWindowSize.width();
       
   525     int sh = m_filmstripFlowData->m_sideWindowSize.height();
       
   526     int w = m_filmstripFlowData->m_widgetSize.width();
       
   527     int h = m_filmstripFlowData->m_widgetSize.height();
       
   528 
       
   529     qreal step = ANIMATION_MAX_FRAME;
       
   530     qreal cx = (w + 4 * m_filmstripFlowData->m_space + cw) / 2.0 - m_filmstripFlowData->m_space;
       
   531     qreal cy = m_filmstripFlowData->m_centerTopSpace;
       
   532     qreal sx = (((w + 4 * m_filmstripFlowData->m_space) + cw) / 2.0) + sw; 
       
   533     qreal sy = m_filmstripFlowData->m_sideTopSpace;
       
   534     qreal stepx = (sx - cx) / step;
       
   535     qreal stepy = (sy - cy) / step;
       
   536     qreal stepx2 = stepx + (sw - cw) / step;
       
   537     qreal stepy2 = stepy + (sh - ch) / step;
       
   538   
       
   539     QRectF startRect = QRectF(cx, cy, cw, ch);
       
   540     QRectF endRect = QRectF(sx, sy, sw, sh);
       
   541     addRectByFrame(movie, startRect, endRect, stepx, stepy, stepx2, stepy2);
       
   542    
       
   543 }
       
   544 
       
   545 void FilmstripMovieFactory::createRightRightToRightMovie(FilmstripMovie* movie)
       
   546 {
       
   547     movie->m_movieClips.clear();
       
   548     int cw = m_filmstripFlowData->m_centerWindowSize.width();
       
   549     int ch = m_filmstripFlowData->m_centerWindowSize.height();
       
   550     int sw = m_filmstripFlowData->m_sideWindowSize.width();
       
   551     int sh = m_filmstripFlowData->m_sideWindowSize.height();
       
   552     int w = m_filmstripFlowData->m_widgetSize.width();
       
   553     int h = m_filmstripFlowData->m_widgetSize.height();
       
   554 
       
   555     qreal step = ANIMATION_MAX_FRAME;
       
   556     qreal cx = (w + 4 * m_filmstripFlowData->m_space + cw) / 2.0 - m_filmstripFlowData->m_space;
       
   557     qreal cy = m_filmstripFlowData->m_centerTopSpace;
       
   558     qreal sx = ((w + 4 * m_filmstripFlowData->m_space) + cw) / 2.0 + sw; 
       
   559     qreal sy = m_filmstripFlowData->m_sideTopSpace;
       
   560     qreal stepx = (cx - sx) / step;
       
   561     qreal stepy = (cy - sy) / step;
       
   562     qreal stepx2 = stepx + (cw - sw) / step;
       
   563     qreal stepy2 = stepy + (ch - sh) / step;
       
   564  
       
   565     QRectF startRect = QRectF(sx, sy, sw, sh);
       
   566     QRectF endRect = QRectF(cx, cy, cw, ch);
       
   567 
       
   568     addRectByFrame(movie, startRect, endRect, stepx, stepy, stepx2, stepy2);
       
   569 }
       
   570 
       
   571 
       
   572 void FilmstripMovieFactory::addRectByFrame(FilmstripMovie* movie, QRectF& startRect, QRectF& endRect, qreal x1, qreal y1, qreal x2, qreal y2, bool debug)
       
   573 {
       
   574     movie->m_movieClips.append(startRect);
       
   575     if (debug)
       
   576         qDebug() << "0:" << startRect;
       
   577     for (int i = 1; i < ANIMATION_MAX_FRAME; i++) {
       
   578         if (debug)
       
   579             qDebug() << i << ":" << movie->m_movieClips[i - 1].adjusted(x1, y1, x2, y2);
       
   580         movie->m_movieClips.append(movie->m_movieClips[i - 1].adjusted(x1, y1, x2, y2));
       
   581     }
       
   582     movie->m_movieClips.append(endRect);
       
   583     if (debug)
       
   584         qDebug() << movie->m_movieClips.size() - 1 << ":"  << endRect;
       
   585 }
       
   586 
       
   587 void FilmstripMovieFactory::createLeftToCenterMovie(FilmstripMovie* movie)
       
   588 {
       
   589     movie->m_movieClips.clear();
       
   590     int cw = m_filmstripFlowData->m_centerWindowSize.width();
       
   591     int ch = m_filmstripFlowData->m_centerWindowSize.height();
       
   592     int sw = m_filmstripFlowData->m_sideWindowSize.width();
       
   593     int sh = m_filmstripFlowData->m_sideWindowSize.height();
       
   594     int w = m_filmstripFlowData->m_widgetSize.width();
       
   595     int h = m_filmstripFlowData->m_widgetSize.height();
       
   596 
       
   597     qreal step = ANIMATION_MAX_FRAME;
       
   598     qreal cx = (w - cw) / 2.0;
       
   599     qreal cy = m_filmstripFlowData->m_centerTopSpace;
       
   600     qreal sx = (((w  - 4 * m_filmstripFlowData->m_space) - cw) / 2.0) - sw + m_filmstripFlowData->m_space;
       
   601     qreal sy = m_filmstripFlowData->m_sideTopSpace;
       
   602     qreal stepx = (cx - sx) / step;
       
   603     qreal stepy = (cy - sy) / step;
       
   604     qreal stepx2 = stepx + (cw - sw) / step;
       
   605     qreal stepy2 = stepy + (ch - sh) / step;
       
   606 
       
   607     QRectF startRect = QRectF(sx, sy, sw, sh);
       
   608     QRectF endRect = QRectF(cx, cy, cw, ch);
       
   609 
       
   610     addRectByFrame(movie, startRect, endRect, stepx, stepy, stepx2, stepy2);
       
   611 }
       
   612 
       
   613 void FilmstripMovieFactory::createRightToCenterMovie(FilmstripMovie* movie)
       
   614 {
       
   615     movie->m_movieClips.clear();
       
   616     int cw = m_filmstripFlowData->m_centerWindowSize.width();
       
   617     int ch = m_filmstripFlowData->m_centerWindowSize.height();
       
   618     int sw = m_filmstripFlowData->m_sideWindowSize.width();
       
   619     int sh = m_filmstripFlowData->m_sideWindowSize.height();
       
   620     int w = m_filmstripFlowData->m_widgetSize.width();
       
   621     int h = m_filmstripFlowData->m_widgetSize.height();
       
   622 
       
   623     qreal step = ANIMATION_MAX_FRAME;
       
   624     qreal cx = (w - cw) / 2.0;
       
   625     qreal cy = m_filmstripFlowData->m_centerTopSpace;
       
   626     qreal sx = ((w + 4 * m_filmstripFlowData->m_space) + cw) / 2.0 - m_filmstripFlowData->m_space; 
       
   627     qreal sy = m_filmstripFlowData->m_sideTopSpace;
       
   628     qreal stepx = (cx - sx) / step;
       
   629     qreal stepy = (cy - sy) / step;
       
   630     qreal stepx2 = stepx + (cw - sw) / step;
       
   631     qreal stepy2 = stepy + (ch - sh) / step;
       
   632 
       
   633     QRectF startRect = QRectF(sx, sy, sw, sh);
       
   634     QRectF endRect = QRectF(cx, cy, cw, ch);
       
   635 
       
   636     addRectByFrame(movie, startRect, endRect, stepx, stepy, stepx2, stepy2);
       
   637 }
       
   638 
       
   639 void FilmstripMovieFactory::createCenterToLeftMovie(FilmstripMovie* movie)
       
   640 {
       
   641     movie->m_movieClips.clear();
       
   642     int cw = m_filmstripFlowData->m_centerWindowSize.width();
       
   643     int ch = m_filmstripFlowData->m_centerWindowSize.height();
       
   644     int sw = m_filmstripFlowData->m_sideWindowSize.width();
       
   645     int sh = m_filmstripFlowData->m_sideWindowSize.height();
       
   646     int w = m_filmstripFlowData->m_widgetSize.width();
       
   647     int h = m_filmstripFlowData->m_widgetSize.height();
       
   648 
       
   649     qreal step = ANIMATION_MAX_FRAME;
       
   650     qreal cx = (w - cw) / 2.0;
       
   651     qreal cy = m_filmstripFlowData->m_centerTopSpace;
       
   652     qreal sx = (((w - 4 * m_filmstripFlowData->m_space) - cw) / 2.0) - sw + m_filmstripFlowData->m_space; 
       
   653     qreal sy = m_filmstripFlowData->m_sideTopSpace;
       
   654     qreal stepx = (sx - cx) / step;
       
   655     qreal stepy = (sy - cy) / step;
       
   656     qreal stepx2 = stepx + (sw - cw) / step;
       
   657     qreal stepy2 = stepy + (sh - ch) / step;
       
   658 
       
   659     QRectF startRect = QRectF(cx, cy, cw, ch);
       
   660     QRectF endRect = QRectF(sx, sy, sw, sh);
       
   661     addRectByFrame(movie, startRect, endRect, stepx, stepy, stepx2, stepy2);
       
   662   }
       
   663 
       
   664 void FilmstripMovieFactory::createCenterToRightMovie(FilmstripMovie* movie)
       
   665 {
       
   666     movie->m_movieClips.clear();
       
   667     int cw = m_filmstripFlowData->m_centerWindowSize.width();
       
   668     int ch = m_filmstripFlowData->m_centerWindowSize.height();
       
   669     int sw = m_filmstripFlowData->m_sideWindowSize.width();
       
   670     int sh = m_filmstripFlowData->m_sideWindowSize.height();
       
   671     int w = m_filmstripFlowData->m_widgetSize.width();
       
   672     int h = m_filmstripFlowData->m_widgetSize.height();
       
   673 
       
   674     qreal step = ANIMATION_MAX_FRAME;
       
   675     qreal cx = (w - cw) / 2.0;
       
   676     qreal cy = m_filmstripFlowData->m_centerTopSpace;
       
   677     qreal sx = (((w + 4 * m_filmstripFlowData->m_space) + cw) / 2.0) - m_filmstripFlowData->m_space;
       
   678     qreal sy = m_filmstripFlowData->m_sideTopSpace;
       
   679     qreal stepx = (sx - cx) / step;
       
   680     qreal stepy = (sy - cy) / step;
       
   681     qreal stepx2 = stepx + (sw - cw) / step;
       
   682     qreal stepy2 = stepy + (sh - ch) / step;
       
   683 
       
   684     QRectF startRect = QRectF(cx, cy, cw, ch);
       
   685     QRectF endRect = QRectF(sx, sy, sw, sh);
       
   686     addRectByFrame(movie, startRect, endRect, stepx, stepy, stepx2, stepy2);
       
   687 }
       
   688 
       
   689 void FilmstripMovieFactory::createLeftOutMovie(FilmstripMovie* movie)
       
   690 {
       
   691     movie->m_movieClips.clear();
       
   692     int cw = m_filmstripFlowData->m_centerWindowSize.width();
       
   693     int sw = m_filmstripFlowData->m_sideWindowSize.width();
       
   694     int sh = m_filmstripFlowData->m_sideWindowSize.height();
       
   695     int w = m_filmstripFlowData->m_widgetSize.width();
       
   696     int h = m_filmstripFlowData->m_widgetSize.height();
       
   697 
       
   698     qreal cx = (w - cw) / 2.0;
       
   699     qreal sx = (w * (1 - 2 * m_filmstripFlowData->m_space) - cw) / 2.0 - sw;
       
   700     qreal sy = m_filmstripFlowData->m_sideTopSpace;
       
   701     qreal stepx = (sx -cx) / ANIMATION_MAX_FRAME;
       
   702  
       
   703     QRectF startRect = QRectF(sx, sy, sw, sh);
       
   704     QRectF endRect = QRectF(2 * sx - cx , sy, sw, sh);
       
   705 
       
   706     addRectByFrame(movie, startRect, endRect, stepx, 0, stepx, 0);
       
   707 }
       
   708 
       
   709 void FilmstripMovieFactory::createLeftInMovie(FilmstripMovie* movie)
       
   710 {
       
   711     movie->m_movieClips.clear();
       
   712     int cw = m_filmstripFlowData->m_centerWindowSize.width();
       
   713     int sw = m_filmstripFlowData->m_sideWindowSize.width();
       
   714     int sh = m_filmstripFlowData->m_sideWindowSize.height();
       
   715     int w = m_filmstripFlowData->m_widgetSize.width();
       
   716     int h = m_filmstripFlowData->m_widgetSize.height();
       
   717 
       
   718     qreal cx = (w - cw) / 2.0;
       
   719     qreal sx = (w * (1 - 2 * m_filmstripFlowData->m_space) - cw) / 2.0 - sw; 
       
   720     qreal sy = m_filmstripFlowData->m_sideTopSpace;
       
   721     qreal stepx = (cx - sx) / ANIMATION_MAX_FRAME;
       
   722     
       
   723     QRectF startRect = QRectF(2 * sx - cx , sy, sw, sh);
       
   724     QRectF endRect = QRectF(sx, sy, sw, sh);
       
   725 
       
   726     addRectByFrame(movie, startRect, endRect, stepx, 0, stepx, 0);
       
   727 }
       
   728 
       
   729 void FilmstripMovieFactory::createRightOutMovie(FilmstripMovie* movie)
       
   730 {
       
   731     movie->m_movieClips.clear();
       
   732     int cw = m_filmstripFlowData->m_centerWindowSize.width();
       
   733     int sw = m_filmstripFlowData->m_sideWindowSize.width();
       
   734     int sh = m_filmstripFlowData->m_sideWindowSize.height();
       
   735     int w = m_filmstripFlowData->m_widgetSize.width();
       
   736     int h = m_filmstripFlowData->m_widgetSize.height();
       
   737 
       
   738     qreal cx = (w - cw) / 2.0;
       
   739     qreal sx = (w * (1 + 2 * m_filmstripFlowData->m_space) + cw) / 2.0; 
       
   740     qreal sy = m_filmstripFlowData->m_sideTopSpace;
       
   741     qreal stepx = (sx - cx) / ANIMATION_MAX_FRAME;
       
   742 
       
   743     QRectF startRect = QRectF(sx, sy, sw, sh);
       
   744     QRectF endRect = QRectF(sx + sx -cx, sy, sw, sh);
       
   745     addRectByFrame(movie, startRect, endRect, stepx, 0, stepx, 0);
       
   746 }
       
   747 
       
   748 void FilmstripMovieFactory::createRightInMovie(FilmstripMovie* movie)
       
   749 {
       
   750     movie->m_movieClips.clear();
       
   751     int cw = m_filmstripFlowData->m_centerWindowSize.width();
       
   752     int sw = m_filmstripFlowData->m_sideWindowSize.width();
       
   753     int sh = m_filmstripFlowData->m_sideWindowSize.height();
       
   754     int w = m_filmstripFlowData->m_widgetSize.width();
       
   755     int h = m_filmstripFlowData->m_widgetSize.height();
       
   756 
       
   757     qreal cx = (w - cw) / 2.0;
       
   758     qreal sx = (w * (1 + 2 * m_filmstripFlowData->m_space) + cw) / 2.0; 
       
   759     qreal sy = m_filmstripFlowData->m_sideTopSpace;
       
   760     qreal stepx = (cx - sx) / ANIMATION_MAX_FRAME;
       
   761 
       
   762     QRectF startRect = QRectF(sx + sx -cx, sy, sw, sh);
       
   763     QRectF endRect = QRectF(sx, sy, sw, sh);
       
   764 
       
   765     addRectByFrame(movie, startRect, endRect, stepx, 0, stepx, 0);
       
   766 }
       
   767 
       
   768 void FilmstripMovieFactory::createFadeOutMovie(FilmstripMovie* movie)
       
   769 {
       
   770     movie->m_movieClips.clear();
       
   771     int cw = m_filmstripFlowData->m_centerWindowSize.width();
       
   772     int ch = m_filmstripFlowData->m_centerWindowSize.height();
       
   773     int w = m_filmstripFlowData->m_widgetSize.width();
       
   774 
       
   775     qreal cx = (w - cw) / 2.0;
       
   776     qreal cy = m_filmstripFlowData->m_centerTopSpace;
       
   777 
       
   778     QRectF startRect = QRectF(cx, cy, cw, ch);
       
   779     movie->m_movieClips.append(startRect);
       
   780     
       
   781     movie->m_movieType = FilmstripMovie::FADE_OUT;
       
   782 }
       
   783 
       
   784 void FilmstripMovieFactory::createZoomInMovie(FilmstripMovie* movie)
       
   785 {
       
   786     movie->m_movieClips.clear();
       
   787     int w = m_filmstripFlowData->m_widgetSize.width();
       
   788     int h = m_filmstripFlowData->m_widgetSize.height();
       
   789     int cw = m_filmstripFlowData->m_centerWindowSize.width();
       
   790     int ch = m_filmstripFlowData->m_centerWindowSize.height();
       
   791 
       
   792     qreal step = ANIMATION_MAX_FRAME;
       
   793     qreal cx = (w - cw) / 2.0;
       
   794     qreal cy = m_filmstripFlowData->m_centerTopSpace;
       
   795 
       
   796     qreal stepx = - cx / step;
       
   797     qreal stepy = - cy / step;
       
   798     qreal stepx2 = - stepx;
       
   799     qreal stepy2 = (h - cy - ch) / step;
       
   800  
       
   801     QRectF startRect = QRectF(cx, cy, cw, ch);
       
   802     QRectF endRect = QRectF(0, 0, w, h);
       
   803 
       
   804     addRectByFrame(movie, startRect, endRect, stepx, stepy, stepx2, stepy2);
       
   805 }
       
   806 
       
   807 void FilmstripMovieFactory::createZoomOutMovie(FilmstripMovie* movie)
       
   808 {
       
   809     movie->m_movieClips.clear();
       
   810     int w = m_filmstripFlowData->m_widgetSize.width();
       
   811     int h = m_filmstripFlowData->m_widgetSize.height();
       
   812     int cw = m_filmstripFlowData->m_centerWindowSize.width();
       
   813     int ch = m_filmstripFlowData->m_centerWindowSize.height();
       
   814     qreal cx = (w - cw) / 2.0;
       
   815 
       
   816     qreal step = ANIMATION_MAX_FRAME;
       
   817     qreal cy = m_filmstripFlowData->m_centerTopSpace;
       
   818 
       
   819     qreal stepx = cx / step;
       
   820     qreal stepy = cy / step;
       
   821     qreal stepx2 = -stepx;
       
   822     qreal stepy2 = (cy + ch - h) / step;
       
   823 
       
   824     QRectF startRect = QRectF(0, 0, w, h);
       
   825     QRectF endRect = QRectF(cx, cy, cw, ch);
       
   826 
       
   827     addRectByFrame(movie, startRect, endRect, 0, stepy, 0, stepy);
       
   828 }
       
   829 
       
   830 void FilmstripMovieFactory::updateAllMovie()
       
   831 {
       
   832     QHash<QString, FilmstripMovie*>::const_iterator i = m_moviesCache.find(BreakoutRightRight);
       
   833 
       
   834     if (i != m_moviesCache.end()) {
       
   835         FilmstripMovie* movie =  m_moviesCache.value(BreakoutRightRight);
       
   836         createRightRightOutMovie(movie);
       
   837     }
       
   838 
       
   839     i = m_moviesCache.find(CenterToLeft);
       
   840     if (i != m_moviesCache.end()) {
       
   841         FilmstripMovie* movie =  m_moviesCache.value(CenterToLeft);
       
   842         createCenterToLeftMovie(movie);
       
   843     }
       
   844 
       
   845     i = m_moviesCache.find(CenterToRight);
       
   846     if (i != m_moviesCache.end()) {
       
   847         FilmstripMovie* movie =  m_moviesCache.value(CenterToRight);
       
   848         createCenterToRightMovie(movie);
       
   849     }
       
   850 
       
   851     i = m_moviesCache.find(LeftToCenter);
       
   852     if (i != m_moviesCache.end()) {
       
   853         FilmstripMovie* movie =  m_moviesCache.value(LeftToCenter);
       
   854         createLeftToCenterMovie(movie);
       
   855     }
       
   856 
       
   857     i = m_moviesCache.find(RightToCenter);
       
   858     if (i != m_moviesCache.end()) {
       
   859         FilmstripMovie* movie =  m_moviesCache.value(RightToCenter);
       
   860         createRightToCenterMovie(movie);
       
   861     }
       
   862 
       
   863     i = m_moviesCache.find(FadeOut);
       
   864     if (i != m_moviesCache.end()) {
       
   865         FilmstripMovie* movie =  m_moviesCache.value(FadeOut);
       
   866         createFadeOutMovie(movie);
       
   867     }
       
   868 
       
   869     i = m_moviesCache.find(ZoomIn);
       
   870     if (i != m_moviesCache.end()) {
       
   871         FilmstripMovie* movie =  m_moviesCache.value(ZoomIn);
       
   872         createZoomInMovie(movie);
       
   873     }
       
   874 
       
   875     i = m_moviesCache.find(ZoomOut);
       
   876     if (i != m_moviesCache.end()) {
       
   877         FilmstripMovie* movie =  m_moviesCache.value(ZoomOut);
       
   878         createZoomOutMovie(movie);
       
   879     }
       
   880 
       
   881     i = m_moviesCache.find(BreakinLeftLeft);
       
   882     if (i != m_moviesCache.end()) {
       
   883         FilmstripMovie* movie =  m_moviesCache.value(BreakinLeftLeft);
       
   884         createLeftLeftInMovie(movie);
       
   885     }
       
   886 
       
   887     
       
   888     i = m_moviesCache.find(BreakinRightRight);
       
   889     if (i != m_moviesCache.end()) {
       
   890         FilmstripMovie* movie =  m_moviesCache.value(BreakinRightRight);
       
   891         createRightRightInMovie(movie);
       
   892     }
       
   893     
       
   894     i = m_moviesCache.find(BreakoutLeftLeft);
       
   895     if (i != m_moviesCache.end()) {
       
   896         FilmstripMovie* movie =  m_moviesCache.value(BreakoutLeftLeft);
       
   897         createLeftLeftOutMovie(movie);
       
   898     }
       
   899     
       
   900     i = m_moviesCache.find(BreakoutRightRight);
       
   901     if (i != m_moviesCache.end()) {
       
   902         FilmstripMovie* movie =  m_moviesCache.value(BreakoutRightRight);
       
   903         createRightRightOutMovie(movie);
       
   904     }
       
   905     
       
   906     i = m_moviesCache.find(LeftLeftToLeft);
       
   907     if (i != m_moviesCache.end()) {
       
   908         FilmstripMovie* movie =  m_moviesCache.value(LeftLeftToLeft);
       
   909         createLeftLeftToLeftMovie(movie);
       
   910     } 
       
   911     
       
   912     i = m_moviesCache.find(LeftToLeftLeft);
       
   913     if (i != m_moviesCache.end()) {
       
   914         FilmstripMovie* movie =  m_moviesCache.value(LeftToLeftLeft);
       
   915         createLeftToLeftLeftMovie(movie);
       
   916     } 
       
   917     
       
   918     i = m_moviesCache.find(RightToRightRight);
       
   919     if (i != m_moviesCache.end()) {
       
   920         FilmstripMovie* movie =  m_moviesCache.value(RightToRightRight);
       
   921         createRightToRightRightMovie(movie);
       
   922     } 
       
   923     
       
   924     i = m_moviesCache.find(RightRightToRight);
       
   925     if (i != m_moviesCache.end()) {
       
   926         FilmstripMovie* movie =  m_moviesCache.value(RightRightToRight);
       
   927         createRightRightToRightMovie(movie);
       
   928     }
       
   929 }
       
   930 
       
   931 // -------------------------------------------------------
       
   932 // LinearFlowSnippet.
       
   933 /*!
       
   934   Creates a new LinearFlowSnippet.
       
   935 */  
       
   936 LinearFlowSnippet::LinearFlowSnippet(QGraphicsWidget* parent): QGraphicsWidget(parent), d(new FilmstripFlowPrivate())
       
   937 {
       
   938     setParent(parent);
       
   939     m_scrolled = false;
       
   940     m_displayMode = "";
       
   941     m_titleName = "";
       
   942     m_countFlicks = 0;
       
   943 }
       
   944 
       
   945 /*!
       
   946   Destroys the widget.
       
   947 */
       
   948 LinearFlowSnippet::~LinearFlowSnippet()
       
   949 {
       
   950     delete d;
       
   951 }
       
   952 
       
   953 /*!
       
   954   Init the FilmstripFlow
       
   955 */
       
   956 void LinearFlowSnippet::init(QString displayMode, QString titleName)
       
   957 {
       
   958     Q_UNUSED(displayMode);
       
   959     Q_UNUSED(titleName);
       
   960 
       
   961     m_displayMode = displayMode;
       
   962     m_titleName = titleName;
       
   963 
       
   964     if (!d->m_closeIcon) {
       
   965         d->m_closeIcon = new QImage("./chrome/close.png");
       
   966     }
       
   967     d->m_movieFactory.setFilmstripFlowData(d);
       
   968 
       
   969     d->m_movieTimer.setDuration(ANIMATION_DURATION);
       
   970     d->m_movieTimer.setCurveShape(QTimeLine::EaseOutCurve);
       
   971     d->m_movieTimer.setFrameRange(0, ANIMATION_MAX_FRAME);
       
   972     QObject::connect(&d->m_movieTimer, SIGNAL(frameChanged(int)), this, SLOT(playMovie(int)));
       
   973     QObject::connect(&d->m_movieTimer, SIGNAL(finished()), this, SLOT(stopMovie()));
       
   974 
       
   975     QSize s = size().toSize();
       
   976     d->m_widgetSize = s;
       
   977     adjustFilmstripSize(s);
       
   978     // ensure that system cursor is an arrow, not a random icon
       
   979     // This is not an issue if the platform does not have a system cursor
       
   980 #ifndef __SYMBIAN32__
       
   981     setCursor(Qt::ArrowCursor);
       
   982 #endif
       
   983     setFocusPolicy(Qt::WheelFocus);
       
   984     setFocus(Qt::OtherFocusReason);
       
   985 }
       
   986 
       
   987 /*!
       
   988   Set center index
       
   989 */
       
   990 void LinearFlowSnippet::setCenterIndex(int i) 
       
   991 {
       
   992     Q_ASSERT(d);
       
   993     if (!d->m_films.size())
       
   994         return;
       
   995     
       
   996     if(d->m_centerIndex == i)
       
   997         return;
       
   998 
       
   999     if(i < 0)
       
  1000         i = (d->m_films.size() + i);
       
  1001     else if(d->m_centerIndex >= d->m_films.size() - 1)
       
  1002         i = i % d->m_films.size();
       
  1003 
       
  1004     d->m_centerIndex = i;
       
  1005   
       
  1006     CALL_ON_PREV_PREV_PREV_FILM_STRIP(updateMovie(NULL));
       
  1007     CALL_ON_NEXT_NEXT_NEXT_FILM_STRIP(updateMovie(NULL));
       
  1008     d->m_films[d->m_centerIndex]->updateMovie(d->m_movieFactory.createMovie(CenterToRight));
       
  1009     CALL_ON_PREV_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(LeftToCenter)));
       
  1010     CALL_ON_PREV_PREV_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(LeftLeftToLeft))); 
       
  1011     CALL_ON_NEXT_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(RightToRightRight)));
       
  1012     CALL_ON_NEXT_NEXT_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(BreakoutRightRight))); 
       
  1013 
       
  1014     emit centerIndexChanged(i);
       
  1015 }
       
  1016 
       
  1017 /*!
       
  1018   add slide
       
  1019 */
       
  1020 void LinearFlowSnippet::addSlide(const QImage& image)
       
  1021 {
       
  1022     Q_ASSERT(d);
       
  1023     Filmstrip* filmstrip = new Filmstrip(image, d);
       
  1024     d->m_films.append(filmstrip);
       
  1025 }
       
  1026 
       
  1027 /*!
       
  1028   add slide
       
  1029 */
       
  1030 void LinearFlowSnippet::addSlide(const QImage& image, const QString& title)
       
  1031 {
       
  1032     Q_ASSERT(d);
       
  1033     Filmstrip* filmstrip = new Filmstrip(image, d);
       
  1034     filmstrip->setName(title);
       
  1035     d->m_films.append(filmstrip);
       
  1036 }
       
  1037 
       
  1038 /*!
       
  1039   Inserts filmstrip at index position i.
       
  1040   If i is 0, the filmstrip is prepended to the film list. 
       
  1041   If i is size(), the value is appended to the film list.
       
  1042 */
       
  1043 void LinearFlowSnippet::insert(int i, const QImage& image, const QString& title)
       
  1044 {
       
  1045     Q_ASSERT(d);
       
  1046     Q_ASSERT(i >= 0 && i <= d->m_films.size());
       
  1047 
       
  1048     Filmstrip* filmstrip = new Filmstrip(image, d);
       
  1049     filmstrip->setName(title);
       
  1050     d->m_films.insert(i, filmstrip);
       
  1051     
       
  1052     if (isVisible()) {
       
  1053         Q_ASSERT(d->m_movieTimer.state() != QTimeLine::Running);
       
  1054         if (i == d->m_centerIndex + 1)  // insert on right
       
  1055             showInsertOnRight();
       
  1056         else if (i == d->m_centerIndex) // insert on left
       
  1057             showInsertOnLeft();
       
  1058     }
       
  1059 }
       
  1060 
       
  1061 /*!
       
  1062   Removes filmstrip at index position i.
       
  1063 */
       
  1064 void LinearFlowSnippet::removeAt (int i)
       
  1065 {
       
  1066     Q_ASSERT(d);
       
  1067     Q_ASSERT(i >= 0 && i < d->m_films.size());
       
  1068 
       
  1069 
       
  1070     if (isVisible()) {
       
  1071         // Not use Q_ASSERT here because the deletion-op is UI buildin -- tap the close button
       
  1072         if (d->m_movieTimer.state() == QTimeLine::Running)
       
  1073             return;
       
  1074 
       
  1075         d->m_films[d->m_centerIndex]->updateMovie(d->m_movieFactory.createMovie(FadeOut)); // move center slide to left            
       
  1076         CALL_ON_PREV_FILM_STRIP(freeze()); // no movement for left slide
       
  1077         CALL_ON_NEXT_FILM_STRIP(freeze()); // no movement for right slide
       
  1078 
       
  1079         QObject::disconnect(&d->m_movieTimer, SIGNAL(finished()), this, SLOT(stopMovie()));
       
  1080         QObject::connect(&d->m_movieTimer, SIGNAL(finished()), this, SLOT(closeAnimation()));
       
  1081         d->m_movieTimer.start();
       
  1082     }
       
  1083     else {
       
  1084         Filmstrip* f = d->m_films.at(i);
       
  1085         d->m_films.removeAt(i);
       
  1086         SAFE_DELETE(f);
       
  1087         d->m_centerIndex = d->m_films.size() - 1;
       
  1088     }
       
  1089 }
       
  1090 
       
  1091 /*!
       
  1092   Return the index of the current center slide
       
  1093 */
       
  1094 int LinearFlowSnippet::centerIndex() const 
       
  1095 {
       
  1096     Q_ASSERT(d);
       
  1097     return d->m_centerIndex;
       
  1098 }
       
  1099 
       
  1100 /*! Clear all slides
       
  1101 */
       
  1102 void LinearFlowSnippet::clear() 
       
  1103 {
       
  1104     Q_ASSERT(d);
       
  1105     d->clear();
       
  1106 }
       
  1107 
       
  1108 void LinearFlowSnippet::backgroundColor(const QRgb& c)
       
  1109 {
       
  1110     Q_ASSERT(d);
       
  1111     d->m_bgColor = c;
       
  1112 }
       
  1113 
       
  1114 int LinearFlowSnippet::slideCount() const 
       
  1115 {
       
  1116     return d ? d->m_films.size() : 0;
       
  1117 }
       
  1118 
       
  1119 //! Returns QImage of specified slide.
       
  1120 QImage LinearFlowSnippet::slide(int i) const
       
  1121 {
       
  1122     Q_ASSERT(d);
       
  1123     Q_ASSERT( i >=0 && i < d->m_films.size());
       
  1124     return d->m_films.at(i)->image();
       
  1125 }
       
  1126 
       
  1127 //! return true if slide animation is ongoing
       
  1128 bool LinearFlowSnippet::slideAnimationOngoing() const 
       
  1129 {
       
  1130     Q_ASSERT(d);
       
  1131     return d->m_movieTimer.state() == QTimeLine::Running;
       
  1132 }
       
  1133 
       
  1134 //! return center slide's rect
       
  1135 QRect LinearFlowSnippet::centralRect() const 
       
  1136 {
       
  1137     Q_ASSERT(d);
       
  1138     int cw = d->m_centerWindowSize.width();
       
  1139     int ch = d->m_centerWindowSize.height();
       
  1140     int w = size().width();
       
  1141     int h = size().height();
       
  1142 
       
  1143     qreal cx = (w - cw) / 2.0;
       
  1144     qreal cy = d->m_centerTopSpace;
       
  1145     return QRect(cx, cy, cw, ch);
       
  1146 }
       
  1147 
       
  1148 //! prepare start-animation
       
  1149 void LinearFlowSnippet::prepareStartAnimation()
       
  1150 {
       
  1151     CALL_ON_PREV_PREV_PREV_FILM_STRIP(updateMovie(NULL)); 
       
  1152     CALL_ON_NEXT_NEXT_NEXT_FILM_STRIP(updateMovie(NULL)); 
       
  1153     CALL_ON_PREV_PREV_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(BreakinLeftLeft))); 
       
  1154     CALL_ON_CENTER_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(LeftToCenter)));
       
  1155     CALL_ON_NEXT_NEXT_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(BreakinRightRight)));
       
  1156     CALL_ON_PREV_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(LeftLeftToLeft)));
       
  1157     CALL_ON_NEXT_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(RightRightToRight)));
       
  1158 }
       
  1159 
       
  1160 //! run start-animation
       
  1161 void LinearFlowSnippet::runStartAnimation()
       
  1162 {
       
  1163     Q_ASSERT(d);
       
  1164     if (d->m_movieTimer.state() == QTimeLine::Running)
       
  1165         return;
       
  1166     d->m_movieTimer.start();
       
  1167 }
       
  1168 
       
  1169 //! run start-animation
       
  1170 void LinearFlowSnippet::runEndAnimation()
       
  1171 {
       
  1172     Q_ASSERT(d);
       
  1173     if (d->m_movieTimer.state() == QTimeLine::Running)
       
  1174         return;
       
  1175     
       
  1176     CALL_ON_PREV_PREV_PREV_FILM_STRIP(freeze());
       
  1177     CALL_ON_NEXT_NEXT_NEXT_FILM_STRIP(freeze());
       
  1178     CALL_ON_PREV_PREV_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(BreakoutLeftLeft)));
       
  1179     CALL_ON_PREV_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(LeftToLeftLeft)));
       
  1180     CALL_ON_CENTER_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(CenterToLeft)));
       
  1181     CALL_ON_NEXT_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(RightToRightRight))); 
       
  1182     CALL_ON_NEXT_NEXT_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(BreakoutRightRight)));
       
  1183 
       
  1184     QObject::disconnect(&d->m_movieTimer, SIGNAL(finished()), this, SLOT(stopMovie()));
       
  1185     QObject::connect(&d->m_movieTimer, SIGNAL(finished()), this, SIGNAL(endAnimationCplt()));
       
  1186     d->m_movieTimer.start();
       
  1187 }
       
  1188 
       
  1189 //! handle the display mode change
       
  1190 void LinearFlowSnippet::displayModeChanged(QString& newMode)
       
  1191 {
       
  1192     Q_UNUSED(newMode);
       
  1193     m_displayMode = newMode;
       
  1194     Q_ASSERT(d);
       
  1195     QSize s = this->size().toSize();
       
  1196     adjustFilmstripSize(s);
       
  1197     update();
       
  1198 }
       
  1199 
       
  1200 // -------------------------------------------------------
       
  1201 // FilmstripFlow: private functions
       
  1202 
       
  1203 void LinearFlowSnippet::adjustFilmstripSize(QSize& s)
       
  1204 {
       
  1205     Q_ASSERT(d);
       
  1206     SAFE_DELETE(d->m_buffer);
       
  1207     SAFE_DELETE(d->m_titleBuffer);
       
  1208     int w = s.width();
       
  1209     int h = s.height() * FILM_HEIGHT;
       
  1210     
       
  1211     qreal ix;
       
  1212     qreal ratio = ((qreal) w) / h;
       
  1213 
       
  1214     d->m_buffer = new QImage (w, h , QImage::Format_RGB32);
       
  1215     d->m_titleBuffer = new QImage(w, s.height() * TITLE_HEIGHT , QImage::Format_RGB32);
       
  1216 
       
  1217     QPainter painter(d->m_titleBuffer);
       
  1218     painter.fillRect(0,0,d->m_titleBuffer->width(),d->m_titleBuffer->height(),d->m_bgColor);
       
  1219 
       
  1220     QFont font;
       
  1221     font.setBold(true);
       
  1222     font.setPixelSize(13);
       
  1223     font.setWeight(QFont::Bold);
       
  1224     painter.setPen(QColor(169,169,169));
       
  1225     painter.setFont(font);
       
  1226     painter.drawText(QPointF(0,s.height() * TITLE_HEIGHT - 3),m_titleName);
       
  1227 
       
  1228     d->m_sideWindowSize = QSize(WIDTH * L_SIDE_WIDTH_P_C, h * L_SIDE_HEIGHT_P_C);
       
  1229     d->m_centerWindowSize = QSize(WIDTH * L_CENTER_WIDTH_P_C, h * L_CENTER_HEIGHT_P_C);
       
  1230     d->m_centerTopSpace = h * L_CENTER_TOP_SPACE_P_C;
       
  1231     d->m_sideTopSpace = h * L_SIDE_TOP_SPACE_P_C ;
       
  1232     
       
  1233     if( m_displayMode == "Portrait") {
       
  1234         d->m_space = ((qreal)w - ( P_MAX_SLIDE - 1) * (qreal)d->m_sideWindowSize.width() -  (qreal)d->m_centerWindowSize.width())/(P_MAX_SLIDE + 1);
       
  1235     }
       
  1236     else {
       
  1237         d->m_space = ((qreal)w - ( L_MAX_SLIDE - 1) * (qreal)d->m_sideWindowSize.width() -  (qreal)d->m_centerWindowSize.width())/(L_MAX_SLIDE + 1);
       
  1238     }
       
  1239 
       
  1240     ix = (WIDTH * (1 + L_CENTER_WIDTH_P_C) - d->m_closeIcon->size().width() + FRAME_WIDTH)/2.0;
       
  1241 
       
  1242     if (d->m_closeIcon && !d->m_closeIcon->isNull()) {
       
  1243         qreal iy = d->m_centerTopSpace - d->m_closeIcon->size().height()/2.0;
       
  1244         d->m_closeIconPos = QPoint(ix, iy);
       
  1245     }
       
  1246     d->m_movieFactory.updateAllMovie();
       
  1247 
       
  1248     if(d->m_centerIndex != -1)  {
       
  1249         if(m_displayMode == "Portrait")
       
  1250             setCenterIndex(d->m_centerIndex - 1);
       
  1251         else
       
  1252             setCenterIndex(d->m_centerIndex + 1);
       
  1253     }
       
  1254 }
       
  1255 
       
  1256 //! insert a new filmstrip on current's right 
       
  1257 void LinearFlowSnippet::showInsertOnRight()
       
  1258 {
       
  1259     Q_ASSERT(d);
       
  1260     d->m_incIndex = 1;
       
  1261     d->m_films[d->m_centerIndex]->updateMovie(d->m_movieFactory.createMovie(CenterToLeft)); // move center slide to left
       
  1262         
       
  1263     CALL_ON_PREV_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(BreakoutLeft))); // move left slide out
       
  1264     CALL_ON_NEXT_NEXT_FILM_STRIP(freeze());// no movement for right slide
       
  1265     d->m_movieTimer.start();
       
  1266 }
       
  1267 
       
  1268 //! insert a new filmstrip on current's right 
       
  1269 void LinearFlowSnippet::showInsertOnLeft()
       
  1270 {
       
  1271     //FIXME
       
  1272     Q_ASSERT(d);
       
  1273     qDebug() << "showInsertOnLeft is not implemented.";
       
  1274 }
       
  1275 
       
  1276 //! Show the previous item 
       
  1277 void LinearFlowSnippet::showPrevious()
       
  1278 {
       
  1279     Q_ASSERT(d);
       
  1280    
       
  1281     d->m_incIndex = -1;
       
  1282     CALL_ON_CENTER_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(CenterToRight)));
       
  1283     CALL_ON_PREV_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(LeftToCenter)));
       
  1284 
       
  1285     CALL_ON_PREV_PREV_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(LeftLeftToLeft)));
       
  1286     CALL_ON_NEXT_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(RightToRightRight)));
       
  1287 
       
  1288     CALL_ON_NEXT_NEXT_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(BreakoutRightRight)));
       
  1289     CALL_ON_PREV_PREV_PREV_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(BreakinLeftLeft)));
       
  1290     
       
  1291     d->m_movieTimer.start();
       
  1292 }
       
  1293 
       
  1294 //! Show the next item
       
  1295 void LinearFlowSnippet::showNext()
       
  1296 {
       
  1297     Q_ASSERT(d);
       
  1298    
       
  1299     d->m_incIndex = 1;
       
  1300     CALL_ON_CENTER_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(CenterToLeft)));
       
  1301     CALL_ON_PREV_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(LeftToLeftLeft)));
       
  1302     CALL_ON_NEXT_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(RightToCenter)));
       
  1303     CALL_ON_NEXT_NEXT_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(RightRightToRight)));
       
  1304     CALL_ON_PREV_PREV_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(BreakoutLeftLeft)));
       
  1305     CALL_ON_NEXT_NEXT_NEXT_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(BreakinRightRight)));
       
  1306 
       
  1307     d->m_movieTimer.start();
       
  1308 }
       
  1309 
       
  1310 void LinearFlowSnippet::scroll()
       
  1311 {
       
  1312     if(d->m_movieTimer.state() == QTimeLine::Running)
       
  1313         return;
       
  1314     
       
  1315     if(d->m_lastMoveEventPos.x() < (size().width() - d->m_centerWindowSize.width())/ 2) {
       
  1316         showPrevious();
       
  1317     }
       
  1318     else if (d->m_lastMoveEventPos.x() > (size().width() + d->m_centerWindowSize.width())/ 2) {
       
  1319         showNext();
       
  1320     }
       
  1321 }
       
  1322 
       
  1323 void LinearFlowSnippet::playMovie(int frame)
       
  1324 {
       
  1325     Q_ASSERT(d);
       
  1326 
       
  1327     CALL_ON_CENTER_FILM_STRIP(updateMovieFrame(frame));
       
  1328     CALL_ON_PREV_FILM_STRIP(updateMovieFrame(frame));
       
  1329     CALL_ON_PREV_PREV_FILM_STRIP(updateMovieFrame(frame));
       
  1330     CALL_ON_PREV_PREV_PREV_FILM_STRIP(updateMovieFrame(frame));
       
  1331     CALL_ON_NEXT_FILM_STRIP(updateMovieFrame(frame));
       
  1332     CALL_ON_NEXT_NEXT_FILM_STRIP(updateMovieFrame(frame));
       
  1333     CALL_ON_NEXT_NEXT_NEXT_FILM_STRIP(updateMovieFrame(frame));
       
  1334 
       
  1335 
       
  1336     update();
       
  1337 }
       
  1338 
       
  1339 void LinearFlowSnippet::stopMovie()
       
  1340 {
       
  1341     Q_ASSERT(d);
       
  1342     int newIndex = d->m_incIndex + d->m_centerIndex;
       
  1343 
       
  1344     if (newIndex < 0)
       
  1345         newIndex = (d->m_films.size() + newIndex);
       
  1346     else if (newIndex >= d->m_films.size())
       
  1347         newIndex = newIndex % d->m_films.size();
       
  1348 
       
  1349     if (newIndex >= 0 && newIndex < d->m_films.size())
       
  1350         setCenterIndex(newIndex);
       
  1351     
       
  1352     update();
       
  1353 
       
  1354     if(m_countFlicks) {
       
  1355         startFlickScroll();
       
  1356     }
       
  1357 }
       
  1358 
       
  1359 void LinearFlowSnippet::closeAnimation()
       
  1360 {
       
  1361     Filmstrip* f = d->m_films.at(d->m_centerIndex);
       
  1362 
       
  1363     if (d->m_centerIndex == 0) { 
       
  1364         d->m_incIndex = 0;      
       
  1365         CALL_ON_NEXT_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(RightToCenter)));
       
  1366         CALL_ON_NEXT_NEXT_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(BreakinRight)));
       
  1367         d->m_films.removeAt(d->m_centerIndex);
       
  1368     } else {
       
  1369         d->m_incIndex = -1;
       
  1370         CALL_ON_PREV_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(LeftToCenter)));
       
  1371         CALL_ON_PREV_PREV_FILM_STRIP(updateMovie(d->m_movieFactory.createMovie(BreakinLeft)));
       
  1372         CALL_ON_NEXT_FILM_STRIP(freeze()); // no movement for right slide
       
  1373         d->m_films.removeAt(d->m_centerIndex);
       
  1374     }
       
  1375 
       
  1376     // clear the closed film now
       
  1377     SAFE_DELETE(f);
       
  1378     // send the signal
       
  1379     emit removed(d->m_centerIndex);
       
  1380 
       
  1381     QObject::disconnect(&d->m_movieTimer, SIGNAL(finished()), this, SLOT(closeAnimation()));
       
  1382     QObject::connect(&d->m_movieTimer, SIGNAL(finished()), this, SLOT(stopMovie()));
       
  1383     d->m_movieTimer.start();
       
  1384 }
       
  1385 
       
  1386 bool LinearFlowSnippet::hitCloseIcon()
       
  1387 {
       
  1388     if (!d->m_closeIcon)
       
  1389         return false;
       
  1390     
       
  1391     int iw = d->m_closeIcon->size().width() / 2;
       
  1392     QPoint p = d->m_lastMoveEventPos - (d->m_closeIconPos + QPoint(iw, iw));
       
  1393     return (p.manhattanLength() < iw + CLOSE_ICON_ADJUST_SIZE) ? true : false;
       
  1394 }
       
  1395 
       
  1396 // -------------------------------------------------------
       
  1397 // FilmstripFlow: override event handler
       
  1398 
       
  1399 void LinearFlowSnippet::resizeEvent(QGraphicsSceneResizeEvent* event)
       
  1400 {
       
  1401     Q_ASSERT(d);
       
  1402     QGraphicsWidget::resizeEvent(event);
       
  1403     d->m_widgetSize = event->newSize().toSize();
       
  1404     //qDebug() << "LinearFlowSnippet::resizeEvent" << d->m_widgetSize;
       
  1405     // not adjust filmstrip size here because the event->size() is whole application's size
       
  1406 }
       
  1407 
       
  1408 void LinearFlowSnippet::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
       
  1409 {
       
  1410     //qDebug() << "!!!!!!!!!!!!!!!!move event" << this->size();   
       
  1411     if( qAbs(qAbs(event->pos().toPoint().x()) - qAbs(d->m_lastMoveEventPos.x())) > 20)
       
  1412     {
       
  1413         if( event->pos().toPoint().x() < event->lastPos().toPoint().x())
       
  1414             showNext();
       
  1415         else
       
  1416             showPrevious();
       
  1417         d->m_lastMoveEventPos = event->pos().toPoint();
       
  1418 
       
  1419         QTime now(QTime::currentTime());
       
  1420    	    m_lastMoveEventTime.setHMS(now.hour(),now.minute(), now.second(), now.msec());
       
  1421     
       
  1422         DragPoint dragPoint;
       
  1423         dragPoint.iPoint = d->m_lastMoveEventPos;
       
  1424         dragPoint.iTime = QTime::currentTime();
       
  1425         m_dragPoints.append(dragPoint);
       
  1426 
       
  1427         while (m_dragPoints.size() > 4)
       
  1428             m_dragPoints.removeFirst();
       
  1429         
       
  1430         m_scrolled= true;
       
  1431     }
       
  1432 }
       
  1433 
       
  1434 bool LinearFlowSnippet::isFlick() 
       
  1435 {
       
  1436     bool flick = false;
       
  1437     QPoint moveSpeed = speed();
       
  1438     int xSpeed = moveSpeed.x();
       
  1439     int ySpeed = moveSpeed.y();
       
  1440      
       
  1441     flick = (qAbs(xSpeed) > THRESHOLD_FLICK_SPEED || 
       
  1442              qAbs(ySpeed) > THRESHOLD_FLICK_SPEED);
       
  1443  
       
  1444     return flick;
       
  1445 }
       
  1446 
       
  1447 QPoint LinearFlowSnippet::speed() 
       
  1448 {
       
  1449     // Speed is only evaluated at the end of the swipe
       
  1450     QPoint dragSpeed(0,0);
       
  1451     qreal time =  dragTime() / 1000;
       
  1452     if (time > 0) {
       
  1453         QPoint distance = currentPos() - previousPos();
       
  1454         dragSpeed.setX((distance.x()) / time);
       
  1455         dragSpeed.setY((distance.y()) / time);
       
  1456     }
       
  1457     return dragSpeed;
       
  1458 }
       
  1459 
       
  1460 QPoint LinearFlowSnippet::currentPos()
       
  1461 {
       
  1462     return m_dragPoints[m_dragPoints.size()-1].iPoint;
       
  1463 }
       
  1464 
       
  1465 QPoint LinearFlowSnippet::previousPos()
       
  1466 {
       
  1467     return m_dragPoints[0].iPoint;
       
  1468 }
       
  1469 
       
  1470 qreal LinearFlowSnippet::dragTime() const
       
  1471 {
       
  1472     if(m_dragPoints.isEmpty())
       
  1473         return 0.0;
       
  1474     else
       
  1475         return  m_dragPoints[0].iTime.msecsTo(m_dragPoints[m_dragPoints.size()-1].iTime);
       
  1476 }
       
  1477 
       
  1478 
       
  1479 void LinearFlowSnippet::moveEvent(QGraphicsSceneMoveEvent* event)
       
  1480 {
       
  1481     d->m_lastMoveEventPos = event->newPos().toPoint();
       
  1482 }
       
  1483 
       
  1484 void LinearFlowSnippet::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
       
  1485 {
       
  1486     QGraphicsSceneMouseEvent iev(event->type());
       
  1487     iev.setPos(event->pos());
       
  1488     //send mouse release event to open the link
       
  1489     mouseReleaseEvent(&iev);
       
  1490 }
       
  1491 
       
  1492 void LinearFlowSnippet::mousePressEvent(QGraphicsSceneMouseEvent* event)
       
  1493 {
       
  1494     emit mouseEvent( event->type());
       
  1495     if(m_countFlicks)
       
  1496         m_countFlicks = 0;
       
  1497     d->m_movieTimer.setDuration(ANIMATION_DURATION);
       
  1498     m_dragPoints.clear();
       
  1499     DragPoint dragPoint;
       
  1500     dragPoint.iPoint = event->pos().toPoint();
       
  1501     dragPoint.iTime = QTime::currentTime();
       
  1502     m_dragPoints.append(dragPoint);
       
  1503     m_scrolled = false; 
       
  1504     m_lastMoveEventTime.setHMS(0,0,0,0);
       
  1505     d->m_lastMoveEventPos = event->pos().toPoint();
       
  1506 }
       
  1507 
       
  1508 void LinearFlowSnippet::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
       
  1509 {    
       
  1510     emit mouseEvent( event->type());
       
  1511     //check whether strip is scrolled
       
  1512     if(!m_scrolled) {
       
  1513         QPoint releasePoint = event->pos().toPoint();
       
  1514 
       
  1515         int cw = d->m_centerWindowSize.width();
       
  1516         int ch = d->m_centerWindowSize.height();
       
  1517         int sw = d->m_sideWindowSize.width();
       
  1518         int sh = d->m_sideWindowSize.height();
       
  1519         int w = d->m_widgetSize.width();
       
  1520         int h = d->m_widgetSize.height();
       
  1521 
       
  1522         qreal leftLeftPageX = (((w - 4 * d->m_space) - cw) / 2.0) - (2 *sw);
       
  1523         qreal rightRightPageX = (w + 4 * d->m_space + cw) / 2.0 + sw;
       
  1524         qreal leftPageX = ((w - 4 * d->m_space) - cw) / 2.0 - sw + d->m_space;
       
  1525         qreal centerPageX = (w - cw)/2.0;
       
  1526         qreal rightPageX = (w + 4 * d->m_space + cw) / 2.0 - d->m_space;
       
  1527         int pageIndex;
       
  1528 
       
  1529         //check for leftleft film
       
  1530         if((releasePoint.x() >= leftLeftPageX) && (releasePoint.x() <= (leftLeftPageX + sw)) && 
       
  1531             (releasePoint.y() >= (d->m_sideTopSpace+ d->m_widgetSize.height() * TITLE_HEIGHT)) && (releasePoint.y() <= (d->m_sideTopSpace + sh + d->m_widgetSize.height() * TITLE_HEIGHT))) {
       
  1532 
       
  1533             pageIndex = d->m_centerIndex - 2;
       
  1534 
       
  1535         }
       
  1536     
       
  1537         //check for left film
       
  1538         else if((releasePoint.x() >= leftPageX) && (releasePoint.x() <= (leftPageX + sw)) && 
       
  1539                     (releasePoint.y() >= (d->m_sideTopSpace+ d->m_widgetSize.height() * TITLE_HEIGHT)) && (releasePoint.y() <= (d->m_sideTopSpace + sh + d->m_widgetSize.height() * TITLE_HEIGHT))) {
       
  1540 
       
  1541             pageIndex = d->m_centerIndex - 1;
       
  1542 
       
  1543         }
       
  1544 
       
  1545         //check for center film
       
  1546         else if((releasePoint.x() >= centerPageX) && (releasePoint.x() <= (centerPageX + cw)) && 
       
  1547                     (releasePoint.y() >= (d->m_centerTopSpace+ d->m_widgetSize.height() * TITLE_HEIGHT)) && (releasePoint.y() <= (d->m_centerTopSpace + ch + d->m_widgetSize.height() * TITLE_HEIGHT))) {
       
  1548             pageIndex = d->m_centerIndex;
       
  1549         }
       
  1550 
       
  1551         //check for right film
       
  1552         else if((releasePoint.x() >= rightPageX) && (releasePoint.x() <= (rightPageX + sw)) && 
       
  1553                     (releasePoint.y() >= (d->m_sideTopSpace+ d->m_widgetSize.height() * TITLE_HEIGHT)) && (releasePoint.y() <= (d->m_sideTopSpace + sh + d->m_widgetSize.height() * TITLE_HEIGHT))) {
       
  1554             pageIndex = d->m_centerIndex + 1;
       
  1555         }
       
  1556 
       
  1557         //check for right right film
       
  1558         else if((releasePoint.x() >= rightRightPageX) && (releasePoint.x() <= (rightRightPageX + sw)) && 
       
  1559                     (releasePoint.y() >= (d->m_sideTopSpace+ d->m_widgetSize.height() * TITLE_HEIGHT)) && (releasePoint.y() <= (d->m_sideTopSpace + sh + d->m_widgetSize.height() * TITLE_HEIGHT))) {
       
  1560             pageIndex = d->m_centerIndex + 2;
       
  1561         }
       
  1562 
       
  1563         //click else where ignore
       
  1564         else  {
       
  1565             return;
       
  1566         }
       
  1567         if( pageIndex < 0)
       
  1568             pageIndex = d->m_films.size() + pageIndex;
       
  1569         else if (pageIndex >= d->m_films.size())
       
  1570             pageIndex = (pageIndex) % d->m_films.size();
       
  1571 
       
  1572         emit ok(pageIndex);
       
  1573     }
       
  1574  
       
  1575     else  {
       
  1576         int msecs = 0;
       
  1577         if (!m_lastMoveEventTime.isNull()) {
       
  1578             //Start deceleration only if the delta since last drag event is less than threshold
       
  1579             QTime now(QTime::currentTime());
       
  1580             msecs = m_lastMoveEventTime.msecsTo(now);
       
  1581             m_lastMoveEventTime.setHMS(0,0,0,0);
       
  1582         }
       
  1583         if((msecs>0) && (msecs < THRESHOLD_FLICK_TIME)) {
       
  1584             if( isFlick()) {
       
  1585                 m_countFlicks = qBound (-MAX_FLICK_SPEED,speed().x(),+MAX_FLICK_SPEED)/((m_displayMode == "portrait") ? 200 : 100);
       
  1586                 startFlickScroll();
       
  1587             }
       
  1588         }
       
  1589     }
       
  1590 }
       
  1591 
       
  1592 void LinearFlowSnippet::startFlickScroll()
       
  1593 { 
       
  1594     d->m_movieTimer.setDuration(qAbs(ANIMATION_DURATION / m_countFlicks));
       
  1595     if(m_countFlicks < 0) {
       
  1596         showNext();
       
  1597         m_countFlicks++;
       
  1598     }
       
  1599     else {
       
  1600         showPrevious();
       
  1601         m_countFlicks--;
       
  1602     }
       
  1603 }
       
  1604 
       
  1605 void LinearFlowSnippet::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
       
  1606 {
       
  1607     Q_ASSERT(d);
       
  1608     Q_ASSERT(d->m_buffer);
       
  1609     Q_ASSERT(d->m_titleBuffer);
       
  1610 
       
  1611     painter->drawImage(QPointF(0,0), *(d->m_titleBuffer));
       
  1612 
       
  1613     d->m_buffer->fill(d->m_bgColor);
       
  1614 
       
  1615     if (d->m_films.size() > 0 && d->m_centerIndex != INVALID_INDEX) {
       
  1616         
       
  1617         QPainter bufPaint(d->m_buffer);
       
  1618         // draw center film strip
       
  1619         CALL_ON_CENTER_FILM_STRIP(paint(&bufPaint));
       
  1620 
       
  1621         // draw left film strip
       
  1622         CALL_ON_PREV_FILM_STRIP(paint(&bufPaint));
       
  1623 
       
  1624         // draw left left film strip
       
  1625         CALL_ON_PREV_PREV_FILM_STRIP(paint(&bufPaint));
       
  1626 
       
  1627         // draw left left film strip
       
  1628         CALL_ON_PREV_PREV_PREV_FILM_STRIP(paint(&bufPaint));
       
  1629 
       
  1630         // draw right film strip
       
  1631         CALL_ON_NEXT_FILM_STRIP(paint(&bufPaint));
       
  1632 
       
  1633         // draw right right film strip
       
  1634         CALL_ON_NEXT_NEXT_FILM_STRIP(paint(&bufPaint));
       
  1635         
       
  1636         // draw right right film strip
       
  1637         CALL_ON_NEXT_NEXT_NEXT_FILM_STRIP(paint(&bufPaint));
       
  1638 
       
  1639         // 1. draw image from the buffer
       
  1640         painter->drawImage(QPoint(0,d->m_widgetSize.height() * TITLE_HEIGHT), *(d->m_buffer));
       
  1641         if (d->m_movieTimer.state() != QTimeLine::Running) {
       
  1642             // 2. draw close icon
       
  1643             if (d->m_films.size() > 1 && d->m_closeIcon)
       
  1644                 painter->drawImage(d->m_closeIconPos, *(d->m_closeIcon));
       
  1645         }
       
  1646     }
       
  1647     else 
       
  1648         painter->drawImage(QPoint(0,d->m_widgetSize.height() * TITLE_HEIGHT), *(d->m_buffer));
       
  1649 }
       
  1650 
       
  1651 } // end of namespace