ganeswidgets/src/hgmediawallrenderer.cpp
changeset 2 49c70dcc3f17
parent 1 e48454f237ca
child 3 c863538fcbb6
equal deleted inserted replaced
1:e48454f237ca 2:49c70dcc3f17
    19 #include "hgquadrenderer.h"
    19 #include "hgquadrenderer.h"
    20 #include "hgquad.h"
    20 #include "hgquad.h"
    21 #include "hgimage.h"
    21 #include "hgimage.h"
    22 #include "HgImageFader.h"
    22 #include "HgImageFader.h"
    23 #include "hgvgquadrenderer.h"
    23 #include "hgvgquadrenderer.h"
       
    24 #include "hgqtquadrenderer.h"
    24 #include <qvector3d>
    25 #include <qvector3d>
    25 #include <qtimer>
    26 #include <qtimer>
    26 #include <qpropertyanimation>
    27 #include <qpropertyanimation>
    27 #include <qstate.h>
    28 #include <qstate.h>
    28 #include <qabstracttransition>
    29 #include <qabstracttransition>
    35 #include <qpainter>
    36 #include <qpainter>
    36 #include <qpaintengine>
    37 #include <qpaintengine>
    37 
    38 
    38 const qreal KPi = 3.1415926535897932384626433832795;
    39 const qreal KPi = 3.1415926535897932384626433832795;
    39 
    40 
       
    41 
    40 static qreal lerp(qreal start, qreal end, qreal t)
    42 static qreal lerp(qreal start, qreal end, qreal t)
    41 {
    43 {
    42     return start * (1.0f - t) + end * t;
    44     return start * (1.0f - t) + end * t;
    43 }
    45 }
    44 
    46 
    55     }
    57     }
    56 private:
    58 private:
    57     QVector3D mValue;
    59     QVector3D mValue;
    58 };
    60 };
    59 
    61 
       
    62 class MyQuaternionAnimation : public QVariantAnimation
       
    63 {
       
    64 public:
       
    65     virtual void updateCurrentValue(const QVariant& value)
       
    66     {
       
    67         mValue = value.value<QQuaternion>();
       
    68     }
       
    69     QQuaternion getValue() const
       
    70     {
       
    71         return mValue;
       
    72     }
       
    73 private:
       
    74     QQuaternion mValue;
       
    75 };
       
    76 
       
    77 
    60 class HgAnimatedQuad
    78 class HgAnimatedQuad
    61 {
    79 {
    62 public:
    80 public:
    63     
    81 
    64     HgAnimatedQuad(HgQuad* start, HgQuad* end, 
    82     static HgAnimatedQuad* createScrollDirectionChangeAnimation(
    65         int duration) : mQuad(start)
    83         HgQuad* a, HgQuad* b, const QMatrix4x4& tm, const QMatrix4x4& rm, 
    66     {        
    84         const QQuaternion& rot, Qt::Orientation orientation, 
    67         mPositionAnimation.setDuration(duration);
    85         int duration)
    68         mPositionAnimation.setKeyValueAt(0, start->position());
    86     {
    69         mPositionAnimation.setKeyValueAt(1.0, end->position());
    87         HgAnimatedQuad* q = new HgAnimatedQuad();
    70         mPositionAnimation.setEasingCurve(QEasingCurve::Linear);
    88         q->mQuad = a;
    71 
    89 
    72         mScaleAnimation.setDuration(duration);
    90         q->mPosition.setEasingCurve(QEasingCurve::InOutCubic);
    73         mScaleAnimation.setKeyValueAt(0, QVector3D(start->scale().x(), start->scale().y(), 0));
    91         q->mPosition.setDuration(duration);
    74         mScaleAnimation.setKeyValueAt(1, QVector3D(end->scale().x(), end->scale().y(), 0));
    92         QVector3D pos = tm * (a->position() * rm);
    75         mScaleAnimation.setEasingCurve(QEasingCurve::Linear);
    93         q->mPosition.setKeyValueAt(0, pos);
    76     
    94         
    77     }
    95         QVector3D pos2;
    78     
    96         
    79     ~HgAnimatedQuad()
    97         if (orientation == Qt::Horizontal)
    80     {
    98         {
    81     }
    99             pos2 = QVector3D(pos.x(), 0, pos.z() + (pos.y() > b->position().y() ? -0.5f : -0.5f));
    82     
   100         }
       
   101         else
       
   102         {
       
   103             pos2 = QVector3D(0, pos.y(), pos.z() + (pos.x() > b->position().x() ? -0.5f : -0.5f));            
       
   104         }
       
   105                 
       
   106         q->mPosition.setKeyValueAt(0.5f, pos2);
       
   107         q->mPosition.setKeyValueAt(1, b->position());
       
   108         
       
   109         q->mRotation.setEasingCurve(QEasingCurve::InOutCubic);
       
   110         q->mRotation.setDuration(duration);
       
   111         q->mRotation.setKeyValueAt(0, rot);
       
   112         q->mRotation.setKeyValueAt(0.5f, QQuaternion::fromAxisAndAngle(QVector3D(1,1,0), 180));
       
   113         q->mRotation.setKeyValueAt(1, b->rotation());
       
   114     
       
   115         return q;
       
   116     }
       
   117     
       
   118     static HgAnimatedQuad* createBasicAnimation(HgQuad* a, HgQuad* b, int duration)
       
   119     {
       
   120         HgAnimatedQuad* q = new HgAnimatedQuad();
       
   121         q->mQuad = a;
       
   122 
       
   123         q->mPosition.setDuration(duration);
       
   124         q->mPosition.setKeyValueAt(0, a->position());
       
   125         q->mPosition.setKeyValueAt(1, b->position());
       
   126         
       
   127         q->mRotation.setDuration(duration);
       
   128         q->mRotation.setKeyValueAt(0, a->rotation());
       
   129         q->mRotation.setKeyValueAt(1, b->rotation());        
       
   130     
       
   131         return q;
       
   132     }
       
   133             
    83     void start()
   134     void start()
    84     {
   135     {
    85         mPositionAnimation.start();
   136         mPosition.start();
    86         mScaleAnimation.start();
   137         mRotation.start();
    87     }
   138     }
    88            
   139            
    89     void update()
   140     void update()
    90     {
   141     {
    91         mQuad->setPosition(mPositionAnimation.currentValue().value<QVector3D>());
   142         mQuad->setPosition(mPosition.currentValue().value<QVector3D>());
    92         QVector3D scale = mScaleAnimation.currentValue().value<QVector3D>();
   143         mQuad->setRotation(mRotation.currentValue().value<QQuaternion>());
    93         mQuad->setScale(QVector2D(scale.x(), scale.y()));
   144     }
    94     }
   145     
    95     
   146     const HgQuad* quad() const
       
   147     {
       
   148         return mQuad;
       
   149     }
       
   150 
       
   151 private:
    96     HgQuad* mQuad;
   152     HgQuad* mQuad;
    97     MyVectorAnimation mPositionAnimation;
   153     MyVectorAnimation mPosition;
    98     MyVectorAnimation mScaleAnimation;
   154     //MyVectorAnimation mScale;
       
   155     MyQuaternionAnimation mRotation;
       
   156     
    99 };
   157 };
   100 
   158 
       
   159 class HgAnimatedQuadFactory
       
   160 {
       
   161 public:
       
   162     virtual HgAnimatedQuad* createQuad(HgQuad* qA, HgQuad* qB) const=0;
       
   163 };
       
   164 
       
   165 class HgScrollDirChangeQuadFactory : public HgAnimatedQuadFactory
       
   166 {
       
   167 public:
       
   168     void setup(Qt::Orientation nextScrollDirection, 
       
   169         const QRectF& rect, const QSizeF& spacing, const QSizeF& size, 
       
   170         int duration)
       
   171     {
       
   172         mNextScrollDirection = nextScrollDirection;
       
   173         mDuration = duration;
       
   174         
       
   175         if (mNextScrollDirection == Qt::Horizontal)
       
   176         {
       
   177             qreal stepY = spacing.height() + size.height();
       
   178             qreal posY = 0.5f - (rect.height() / rect.width() / 2.0 - stepY / 2.0);                
       
   179             tm.translate(-posY,0);
       
   180             rm.rotate(-90, QVector3D(0,0,1));
       
   181             rot = QQuaternion::fromAxisAndAngle(QVector3D(0,0,1), -90);
       
   182         }
       
   183         else if (mNextScrollDirection == Qt::Vertical)
       
   184         {
       
   185             tm.translate(0,0.5f);
       
   186             rm.rotate(90, QVector3D(0,0,1));
       
   187             rot = QQuaternion::fromAxisAndAngle(QVector3D(0,0,1), -90);                
       
   188         }
       
   189         
       
   190         
       
   191     }
       
   192     
       
   193     HgAnimatedQuad* createQuad(HgQuad* qA, HgQuad* qB) const
       
   194     {
       
   195         return HgAnimatedQuad::createScrollDirectionChangeAnimation(qA, qB, 
       
   196             tm, rm, rot, mNextScrollDirection, mDuration);        
       
   197     }
       
   198 private:
       
   199     QMatrix4x4 tm;
       
   200     QMatrix4x4 rm;
       
   201     QQuaternion rot;
       
   202     Qt::Orientation mNextScrollDirection;
       
   203     int mDuration;
       
   204 };
       
   205 
       
   206 class HgRowCountChangeQuadFactory : public HgAnimatedQuadFactory
       
   207 {
       
   208 public:
       
   209     HgRowCountChangeQuadFactory(int duration) : mDuration(duration)
       
   210     {
       
   211         
       
   212     }
       
   213     
       
   214     HgAnimatedQuad* createQuad(HgQuad* qA, HgQuad* qB) const
       
   215     {
       
   216         return HgAnimatedQuad::createBasicAnimation(qA, qB, mDuration);
       
   217     }
       
   218 private:
       
   219     int mDuration;
       
   220 };
       
   221 
       
   222 
   101 HgMediaWallRenderer::HgMediaWallRenderer(HgMediaWallDataProvider* provider, 
   223 HgMediaWallRenderer::HgMediaWallRenderer(HgMediaWallDataProvider* provider, 
   102     Qt::Orientation scrollDirection, bool coverflowMode) :
   224     Qt::Orientation orientation, Qt::Orientation scrollDirection, bool coverflowMode) :
   103     mDataProvider(provider),
   225     mDataProvider(provider),
   104     mRenderer(NULL),
   226     mRenderer(NULL),
   105     mIndicatorRenderer(NULL),
   227     mIndicatorRenderer(NULL),
   106     mRendererInitialized(false),
   228     mRendererInitialized(false),
   107     mOrientation(scrollDirection),
   229     mScrollDirection(scrollDirection),
   108     mNextOrientation(scrollDirection),
   230     mNextScrollDirection(scrollDirection),
       
   231     mOrientation(orientation),
   109     mStateAnimationAlpha(0),
   232     mStateAnimationAlpha(0),
   110     mStateAnimationOnGoing(false),
   233     mStateAnimationOnGoing(false),
   111     mAnimationAlpha(0),
   234     mAnimationAlpha(0),
   112     mOpeningAnimationDuration(500),
       
   113     mOpenedItem(-1),
       
   114     mFlipAngle(qreal(360)),
       
   115     mZoomAmount(qreal(0.5)),
       
   116     mCoverflowMode(coverflowMode),
   235     mCoverflowMode(coverflowMode),
   117     mRowCount(1),
   236     mRowCount(1),
   118     mNextRowCount(1),
   237     mNextRowCount(1),
   119     mStateAnimationDuration(300),
   238     mStateAnimationDuration(500),
   120     mStep(1.1),
   239     mStep(1.1),
   121     mZfar(-2),
   240     mZfar(-2),
   122     mSpacing2D(10,10),
   241     mSpacing2D(10,10),
   123     mImageSize2D(100, 60),
   242     mImageSize2D(100, 60),
   124     mCameraDistance(0),
   243     mCameraDistance(0),
   125     mCameraRotationY(0),
   244     mCameraRotationY(0),
   126     mCameraRotationZ(0),
   245     mCameraRotationZ(0),
   127     mFrontCoverElevation(0.4),
   246     mFrontCoverElevation(0.4),
   128     mReflectionsEnabled(true),
   247     mFrontItemPosition(0,0)
   129     mItemCountChanged(false),
       
   130     mOpenedItemState(ItemClosed),
       
   131     mFrontItemPosition(0,0),
       
   132     mFrontItemPositionSet(false)    
       
   133 {
   248 {
   134     createStateMachine();
   249     createStateMachine();
   135     mImageFader = new HgImageFader();    
   250     mRenderer = new HgQtQuadRenderer(64);
   136     mRenderer = new HgVgQuadRenderer(256);
   251     mRenderer->enableReflections(true);
   137     mRendererInitialized = true;
   252     mRendererInitialized = true;
   138     if (mCoverflowMode) {
   253     if (mCoverflowMode) {
   139         mOrientation = Qt::Horizontal;
   254         mScrollDirection = Qt::Horizontal;
   140         mNextOrientation = mOrientation;
   255         mNextScrollDirection = mScrollDirection;
   141     }
   256     }
   142 }
   257 }
   143 
   258 
   144 HgMediaWallRenderer::~HgMediaWallRenderer()
   259 HgMediaWallRenderer::~HgMediaWallRenderer()
   145 {
   260 {
   146     delete mRenderer;
   261     delete mRenderer;
   147     delete mImageFader;
       
   148     delete mStateMachine;
   262     delete mStateMachine;
   149 }
   263 }
   150 
   264 
   151 
   265 
   152 void HgMediaWallRenderer::setCameraDistance(qreal distance)
   266 void HgMediaWallRenderer::setCameraDistance(qreal distance)
   182 void HgMediaWallRenderer::draw(
   296 void HgMediaWallRenderer::draw(
   183     const QPointF& startPosition,
   297     const QPointF& startPosition,
   184     const QPointF& position, 
   298     const QPointF& position, 
   185     const QPointF& targetPosition, 
   299     const QPointF& targetPosition, 
   186     qreal springVelocity,
   300     qreal springVelocity,
   187     QPainter* painter)
   301     QPainter* painter, 
   188 {
   302     const QTransform& sceneTransform,
       
   303     const QRectF& rect)
       
   304 {
       
   305     // save new rect
       
   306     mRect = rect;
       
   307     
   189     // if still not initialized we cant draw anything
   308     // if still not initialized we cant draw anything
   190     if (!mRendererInitialized)
   309     if (!mRendererInitialized)
   191         return;
   310         return;
   192         
   311         
   193     if (mOrientation != mNextOrientation ||
   312     if (mScrollDirection != mNextScrollDirection)
   194         mRowCount != mNextRowCount)
   313     {
   195     {
   314         startScrollDirectionChangeAnimation(startPosition, position, 
   196                 
   315             targetPosition, springVelocity, painter, sceneTransform,
   197         // save old state of the quads         
   316             rect);
   198         recordState(mOldState);
   317     }
   199         
   318     else if (mRowCount != mNextRowCount)
   200         // goto wanted orientation / rowcount
   319     {
   201         mOrientation = mNextOrientation;
   320         startRowCountChangeAnimation(startPosition, position, 
   202         mRowCount = mNextRowCount;
   321             targetPosition, springVelocity, painter, sceneTransform,
   203         setImageSize(mNextImageSize);
   322             rect);
   204         
       
   205         // setup quads to new state
       
   206         setupRows(startPosition, position, targetPosition, springVelocity, painter);
       
   207 
       
   208         // record state for animation
       
   209         recordState(mNextState);
       
   210 
       
   211         startStateAnimation(painter);
       
   212     }
   323     }
   213     else
   324     else
   214     {
   325     {
   215         if (!mStateAnimationOnGoing)
   326         if (!mStateAnimationOnGoing)
   216         {
   327         {
   221             setupStateAnimation(painter);
   332             setupStateAnimation(painter);
   222         }    
   333         }    
   223     }
   334     }
   224     
   335     
   225     updateCameraMatrices();
   336     updateCameraMatrices();
   226     drawQuads(painter);
   337     drawQuads(painter, sceneTransform);
   227 }
   338 }
   228 
   339 
   229 void HgMediaWallRenderer::setupRows(const QPointF& startPosition,
   340 void HgMediaWallRenderer::setupRows(const QPointF& startPosition,
   230     const QPointF& position, 
   341     const QPointF& position, 
   231     const QPointF& targetPosition, 
   342     const QPointF& targetPosition, 
   241         //setupRow(startPosition, position, targetPosition, springVelocity, painter, 0);
   352         //setupRow(startPosition, position, targetPosition, springVelocity, painter, 0);
   242         setupCoverflow(startPosition, position, targetPosition, springVelocity, painter);
   353         setupCoverflow(startPosition, position, targetPosition, springVelocity, painter);
   243     }
   354     }
   244     else
   355     else
   245     {
   356     {
   246         if (mOrientation == Qt::Vertical)
   357         if (mScrollDirection == Qt::Vertical)
   247         {
   358         {
   248             setupGridPortrait(startPosition, position, targetPosition, 
   359             setupGridPortrait(startPosition, position, targetPosition, 
   249               springVelocity, painter);            
   360               springVelocity, painter);            
   250         }
   361         }
   251         else
   362         else
   254                 springVelocity, painter);
   365                 springVelocity, painter);
   255         }
   366         }
   256     }        
   367     }        
   257 }
   368 }
   258 
   369 
   259 void HgMediaWallRenderer::setFlipAnimationAngle(qreal angleInDegrees)
       
   260 {
       
   261     mFlipAngle = angleInDegrees;
       
   262 }
       
   263     
       
   264 void HgMediaWallRenderer::setOpeningAnimationType(HgMediaWallRenderer::OpeningAnimationType type)
       
   265 {
       
   266     mOpeningAnimationType = type;
       
   267 }
       
   268 
       
   269 void HgMediaWallRenderer::setOpeningAnimationDuration(int msecs)
       
   270 {
       
   271     mOpeningAnimationDuration = msecs;
       
   272 }
       
   273 
       
   274 qreal HgMediaWallRenderer::animationAlpha() const
   370 qreal HgMediaWallRenderer::animationAlpha() const
   275 {
   371 {
   276     return mAnimationAlpha;
   372     return mAnimationAlpha;
   277 }
   373 }
   278 
   374 
   279 void HgMediaWallRenderer::setAnimationAlpha(qreal alpha)
   375 void HgMediaWallRenderer::setAnimationAlpha(qreal alpha)
   280 {
   376 {
   281     mAnimationAlpha = alpha;
   377     mAnimationAlpha = alpha;
   282     
   378         
   283     if (mOpenedItemState == ItemClosing && alpha == 0.0f)
       
   284         mOpenedItemState = ItemClosed;
       
   285     
       
   286     if (mOpenedItemState == ItemOpening && alpha == 1.0f)
       
   287         mOpenedItemState = ItemOpened;
       
   288     
       
   289     emit renderingNeeded();
   379     emit renderingNeeded();
   290 }
   380 }
   291 
   381 
   292 qreal HgMediaWallRenderer::stateAnimationAlpha() const
   382 qreal HgMediaWallRenderer::stateAnimationAlpha() const
   293 {
   383 {
   308 {
   398 {
   309     mStateMachine = new QStateMachine(this);
   399     mStateMachine = new QStateMachine(this);
   310     mStateMachine->setAnimated(true);
   400     mStateMachine->setAnimated(true);
   311     
   401     
   312     QState* root = new QState(QState::ParallelStates);
   402     QState* root = new QState(QState::ParallelStates);
   313     QState* p1 = new QState(root);
       
   314     QState* p2 = new QState(root);
   403     QState* p2 = new QState(root);
   315     
   404         
   316     // create idle/opened states
       
   317     {            
       
   318         QState* idle = new QState(p1);
       
   319         QState* opened = new QState(p1);
       
   320 
       
   321         idle->assignProperty(this, "animationAlpha", qreal(0));                                
       
   322         opened->assignProperty(this, "animationAlpha", qreal(1));
       
   323 
       
   324         // add opening animation
       
   325         QPropertyAnimation* anim1 = new QPropertyAnimation(this, "animationAlpha");
       
   326         anim1->setDuration(mOpeningAnimationDuration);
       
   327         idle->addTransition(this, SIGNAL(toggleItem()), opened)->addAnimation(anim1);
       
   328             
       
   329         // add closing animation
       
   330         QPropertyAnimation* anim2 = new QPropertyAnimation(this, "animationAlpha");
       
   331         anim2->setDuration(mOpeningAnimationDuration);
       
   332         opened->addTransition(this, SIGNAL(toggleItem()), idle)->addAnimation(anim2);
       
   333 
       
   334         QObject::connect(idle, SIGNAL(entered()), this, SLOT(onIdleState()));
       
   335         QObject::connect(opened, SIGNAL(entered()), this, SLOT(onOpenedState()));
       
   336     
       
   337         p1->setInitialState(idle);
       
   338     }
       
   339     
       
   340     // create two states to animate between
   405     // create two states to animate between
   341     {
   406     {
   342         QState* s1 = new QState(p2);
   407         QState* s1 = new QState(p2);
   343         QState* s2 = new QState(p2);
   408         QState* s2 = new QState(p2);
   344 
   409 
   354         s2->addTransition(this, SIGNAL(toggleState()), s1)->addAnimation(anim);        
   419         s2->addTransition(this, SIGNAL(toggleState()), s1)->addAnimation(anim);        
   355 
   420 
   356         p2->setInitialState(s1);        
   421         p2->setInitialState(s1);        
   357     }
   422     }
   358 
   423 
   359     root->setInitialState(p1);
   424     root->setInitialState(p2);
   360     mStateMachine->addState(root);    
   425     mStateMachine->addState(root);    
   361     mStateMachine->setInitialState(root);
   426     mStateMachine->setInitialState(root);
   362     mStateMachine->start();
   427     mStateMachine->start();
   363 
   428 
   364 }
   429 }
   365 
   430 
   366 void HgMediaWallRenderer::onIdleState()
   431 void HgMediaWallRenderer::setScrollDirection(Qt::Orientation scrollDirection, bool animate)
   367 {
       
   368     emit itemClosed(mOpenedItem);
       
   369 }
       
   370 
       
   371 void HgMediaWallRenderer::onOpenedState()
       
   372 {
       
   373     emit itemOpened(mOpenedItem);
       
   374 }
       
   375 
       
   376 void HgMediaWallRenderer::setOrientation(Qt::Orientation orientation, bool animate)
       
   377 {
   432 {
   378     // coverflow is always horizontal
   433     // coverflow is always horizontal
   379     if (mCoverflowMode)
   434     if (mCoverflowMode)
   380     {
   435     {
   381         mOrientation = Qt::Horizontal;
   436         mScrollDirection = Qt::Horizontal;
   382         mNextOrientation = mOrientation;
   437         mNextScrollDirection = mScrollDirection;
   383         return;
   438         return;
   384     }
   439     }
   385     
   440     
   386     if (mOrientation != orientation)
   441     if (mScrollDirection != scrollDirection)
   387     {
   442     {
   388         mStateMachine->setAnimated(animate);
   443         mStateMachine->setAnimated(animate);
   389         mNextOrientation = orientation;
   444         mNextScrollDirection = scrollDirection;
   390 
   445 
   391         if (!animate)
   446         if (!animate)
   392             mOrientation = orientation;
   447             mScrollDirection = scrollDirection;
   393         else
   448         else
   394         {
   449         {
   395             emit renderingNeeded();            
   450             //emit renderingNeeded();            
   396         }
   451         }
   397     }
   452     }
   398 }
   453 }
   399 
   454 
   400 Qt::Orientation HgMediaWallRenderer::getOrientation() const
   455 Qt::Orientation HgMediaWallRenderer::getScrollDirection() const
   401 {
   456 {
   402     return mOrientation;
   457     return mScrollDirection;
   403 }
   458 }
   404 
   459 
   405 void HgMediaWallRenderer::drawQuads(QPainter* painter)
   460 void HgMediaWallRenderer::drawQuads(QPainter* painter, 
   406 {
   461     const QTransform& sceneTransform)
   407     
   462 {
   408     mRenderer->transformQuads(mViewMatrix, mProjMatrix, mRect);
   463     mRenderer->drawQuads(painter, mRect, mViewMatrix, mProjMatrix, mOrientation, 
   409 
   464         sceneTransform);    
   410     mRenderer->drawQuads(mRect, painter);    
       
   411 }
   465 }
   412 
   466 
   413 
   467 
   414 void HgMediaWallRenderer::enableCoverflowMode(bool enabled)
   468 void HgMediaWallRenderer::enableCoverflowMode(bool enabled)
   415 {
   469 {
   451 }
   505 }
   452 
   506 
   453 void HgMediaWallRenderer::recordState(HgMediaWallRenderer::State& state)
   507 void HgMediaWallRenderer::recordState(HgMediaWallRenderer::State& state)
   454 {
   508 {
   455     // cleanup old quads
   509     // cleanup old quads
   456     for (int i = 0; i < state.mQuads.size(); i++)
   510     qDeleteAll(state.mQuads.begin(), state.mQuads.end());    
   457     {
       
   458         delete state.mQuads[i];
       
   459     }
       
   460     
       
   461     state.mQuads.clear();
   511     state.mQuads.clear();
   462     
   512     
   463     // record new quads
   513     // record new quads
   464     for (int i = 0; i < mRenderer->quadCount(); i++)
   514     for (int i = 0; i < mRenderer->quadCount(); i++)
   465     {
   515     {
   466         HgQuad* quad = mRenderer->quad(i);
   516         HgQuad* quad = mRenderer->quad(i);
   467         if (!quad->visible())
   517         if (!quad->visible())
   468             continue;
   518             continue;
   469         
   519         
   470         state.mQuads.append(quad->copy());
   520         int index = quad->userData().toInt();
       
   521         state.mQuads[index] = quad->copy();
   471     }    
   522     }    
   472 }
   523 }
   473 
   524 
   474 void HgMediaWallRenderer::setupStateAnimation(QPainter* painter)
   525 void HgMediaWallRenderer::setupStateAnimation(QPainter* painter)
   475 {
   526 {
   476     Q_UNUSED(painter)
   527     Q_UNUSED(painter)
   477     
   528     
   478     resetQuads();
   529     resetQuads();
       
   530     updateSpacingAndImageSize();
       
   531 
   479     // setup quads from animated state
   532     // setup quads from animated state
   480     for (int i = 0; i < mOldState.mQuads.size(); i++)
   533     for (int i = 0; i < mAnimatedQuads.count(); i++)
   481     {
   534     {
   482         mAnimatedQuads[i]->update();
   535         if (i >= mRenderer->quadCount())
   483         mRenderer->quad(i)->copyFrom(*mOldState.mQuads[i]);
   536             return;
   484     }
   537         
       
   538         mAnimatedQuads[i]->update();        
       
   539         mRenderer->quad(i)->copyFrom(*mAnimatedQuads[i]->quad());
       
   540     }
       
   541     
   485 }
   542 }
   486 
   543 
   487 void HgMediaWallRenderer::resetQuads()
   544 void HgMediaWallRenderer::resetQuads()
   488 {
   545 {
   489     for (int i = 0; i < mRenderer->quadCount(); i++)
   546     for (int i = 0; i < mRenderer->quadCount(); i++)
   493 HgQuad* HgMediaWallRenderer::getQuadAt(const QPointF& position) const
   550 HgQuad* HgMediaWallRenderer::getQuadAt(const QPointF& position) const
   494 {
   551 {
   495     if (!mRendererInitialized)
   552     if (!mRendererInitialized)
   496         return NULL;
   553         return NULL;
   497         
   554         
   498     return mRenderer->getQuadAt(position);//mapFromWindow(position));
   555     return mRenderer->getQuadAt(position);
   499 }
       
   500 
       
   501 bool HgMediaWallRenderer::isItemOpen() const
       
   502 {
       
   503     return (mOpenedItem != -1 && mAnimationAlpha > 0);
       
   504 }
       
   505 
       
   506 void HgMediaWallRenderer::setRect(const QRectF& windowRect)
       
   507 {
       
   508     mRect = windowRect;
       
   509 }
       
   510 
       
   511 const QRectF& HgMediaWallRenderer::getRect() const
       
   512 {
       
   513     return mRect;
       
   514 }
   556 }
   515 
   557 
   516 void HgMediaWallRenderer::updateCameraMatrices()
   558 void HgMediaWallRenderer::updateCameraMatrices()
   517 {    
   559 {    
   518     QMatrix4x4 view;
   560     QMatrix4x4 view;
   521     
   563     
   522     view.lookAt(QVector3D(0.0, 0.0, 1.0f  + mCameraDistance), 
   564     view.lookAt(QVector3D(0.0, 0.0, 1.0f  + mCameraDistance), 
   523         QVector3D(0.0f, 0.0f, 0.0f), QVector3D(0.0f, 1.0f, 0.0f));
   565         QVector3D(0.0f, 0.0f, 0.0f), QVector3D(0.0f, 1.0f, 0.0f));
   524 
   566 
   525     QMatrix4x4 rot;
   567     QMatrix4x4 rot;
   526     rot.rotate(mCameraRotationZ, QVector3D(0,0,1));
   568     //rot.rotate(mCameraRotationZ, QVector3D(0,0,1));
   527     rot.rotate(mCameraRotationY, QVector3D(0,1,0));
   569     rot.rotate(mCameraRotationY, QVector3D(0,1,0));
   528     view *= rot;
   570     view *= rot;
   529         
   571             
   530     qreal aspect = mRect.width() / mRect.height();
       
   531     
       
   532     QMatrix4x4 proj;
   572     QMatrix4x4 proj;
   533     proj.setToIdentity();
   573     proj.setToIdentity();
   534     
   574     
   535     if (mRect.width() <= mRect.height())
   575     // setup projection matrix so that width of the item wichi has the 
   536     {
   576     // width of the screen has width of 1 in 3D space
   537         qreal aspect = mRect.height() / mRect.width();
   577     qreal aspect = mRect.height() / mRect.width();
   538         proj.frustum(-0.5f, 0.5f, -0.5f*aspect, 0.5f*aspect, 1.0f, 1000.0f);
   578     proj.frustum(-0.5f, 0.5f, -0.5f * aspect, 0.5f * aspect, 1.0f, 1000.0f);
   539     }
   579         
   540     else
       
   541     {
       
   542         qreal aspect = mRect.width() / mRect.height();
       
   543         proj.frustum(-0.5f*aspect, 0.5f*aspect, -0.5f, 0.5f, 1.0f, 1000.0f);
       
   544     }
       
   545 
       
   546     mViewMatrix = view;
   580     mViewMatrix = view;
   547     mProjMatrix = proj;
   581     mProjMatrix = proj;
   548 
   582 
   549     qreal mirrorPlaneY;
   583     qreal mirrorPlaneY;
   550     if (mCoverflowMode)
   584     if (mCoverflowMode)
   560 }
   594 }
   561 
   595 
   562 
   596 
   563 void HgMediaWallRenderer::updateSpacingAndImageSize()
   597 void HgMediaWallRenderer::updateSpacingAndImageSize()
   564 {
   598 {
   565     qreal div = mRect.width() <= mRect.height() ? mRect.width() : mRect.height();
   599     qreal div = mRect.width();
   566     
   600     
   567     mSpacing3D = mSpacing2D / div;
   601     mSpacing3D = mSpacing2D / div;
   568     mImageSize3D = mImageSize2D / div;
   602     mImageSize3D = mImageSize2D / div;
   569 }
   603 }
   570 
   604 
   597 qreal HgMediaWallRenderer::getFrontCoverElevationFactor() const
   631 qreal HgMediaWallRenderer::getFrontCoverElevationFactor() const
   598 {
   632 {
   599     return mFrontCoverElevation;
   633     return mFrontCoverElevation;
   600 }
   634 }
   601 
   635 
   602 void HgMediaWallRenderer::openItem(int index, bool animate)
       
   603 {
       
   604     if (isItemOpen())
       
   605         return;
       
   606     
       
   607     mOpenedItem = index;
       
   608     mOpenedItemState = animate ? ItemOpening : ItemOpened;
       
   609 
       
   610     mStateMachine->setAnimated(animate);
       
   611     emit toggleItem();
       
   612     
       
   613 }
       
   614 
       
   615 void HgMediaWallRenderer::closeItem(bool animate)
       
   616 {
       
   617     if (!isItemOpen())
       
   618         return;
       
   619 
       
   620     mOpenedItemState = animate ? ItemClosing : ItemClosed;
       
   621     if (!animate)
       
   622         mOpenedItem = -1;
       
   623 
       
   624     mStateMachine->setAnimated(animate);
       
   625     emit toggleItem();
       
   626 }
       
   627 
       
   628 qreal HgMediaWallRenderer::getRowPosY(int row)
   636 qreal HgMediaWallRenderer::getRowPosY(int row)
   629 {
   637 {
   630     qreal step = mSpacing3D.height() + mImageSize3D.height();            
   638     qreal step = mSpacing3D.height() + mImageSize3D.height();            
   631     return mRowCount == 1 ? qreal(0) : (((qreal)mRowCount/qreal(2)-qreal(0.5)) - (qreal)row) * step; 
   639     return mRowCount == 1 ? qreal(0) : (((qreal)mRowCount/qreal(2)-qreal(0.5)) - (qreal)row) * step; 
   632 }
   640 }
   635 {
   643 {
   636     qreal step = -(mSpacing3D.width() + mImageSize3D.width());                
   644     qreal step = -(mSpacing3D.width() + mImageSize3D.width());                
   637     return mColumnCount == 1 ? qreal(0) : (((qreal)mColumnCount/qreal(2)-qreal(0.5)) - (qreal)col) * step; 
   645     return mColumnCount == 1 ? qreal(0) : (((qreal)mColumnCount/qreal(2)-qreal(0.5)) - (qreal)col) * step; 
   638 }
   646 }
   639 
   647 
   640 
       
   641 void HgMediaWallRenderer::enableReflections(bool enabled)
   648 void HgMediaWallRenderer::enableReflections(bool enabled)
   642 {
   649 {
   643     mReflectionsEnabled = enabled;
   650     mRenderer->enableReflections(enabled);
   644 }
   651 }
   645 
   652 
   646 bool HgMediaWallRenderer::reflectionsEnabled() const
   653 bool HgMediaWallRenderer::reflectionsEnabled() const
   647 {
   654 {
   648     return mReflectionsEnabled;
   655     return mRenderer->reflectionsEnabled();
   649 }
   656 }
   650     
   657     
   651 QPointF HgMediaWallRenderer::mapFromWindow(const QPointF& point) const
       
   652 {
       
   653     return QPointF(point.x(), mRect.height() - point.y());
       
   654 }
       
   655 
       
   656 void HgMediaWallRenderer::emitUpdate()
       
   657 {
       
   658     emit renderingNeeded();
       
   659 }
       
   660 
       
   661 void HgMediaWallRenderer::applyOpeningAnimation(HgQuad* quad)
       
   662 {
       
   663     QQuaternion rot(0,0,0,1);
       
   664     qreal rotAngle = mAnimationAlpha * mFlipAngle;
       
   665     rot = QQuaternion::fromAxisAndAngle(QVector3D(0,1,0), rotAngle);
       
   666     quad->setRotation(rot);
       
   667     quad->setPosition(quad->position() + QVector3D(0,0,mAnimationAlpha * mZoomAmount));    
       
   668 }
       
   669 
       
   670 
       
   671 qreal HgMediaWallRenderer::getWorldWidth() const
   658 qreal HgMediaWallRenderer::getWorldWidth() const
   672 {   
   659 {   
   673     qreal width = ceil((qreal)mDataProvider->imageCount() / (qreal)mRowCount - 1.0f);
   660     qreal width = ceil((qreal)mDataProvider->imageCount() / (qreal)mRowCount - 1.0f);
   674     
   661     
   675     // if we are in vertical orientation we want last and first item
   662     // if we are in vertical orientation we want last and first item
   676     // to place at the top and bottom of the screen instead of center
   663     // to place at the top and bottom of the screen instead of center
   677     if (mOrientation == Qt::Vertical)
   664     if (mScrollDirection == Qt::Vertical)
   678     {
   665     {
   679         qreal step = mSpacing2D.height() + mImageSize2D.height(); 
   666         qreal step = mSpacing2D.height() + mImageSize2D.height(); 
   680         width -= (mRect.height() / step - 1.0f);
   667         width -= (mRect.height() / step - 1.0f);
   681     }
   668     }
       
   669     else if (mScrollDirection == Qt::Horizontal && !mCoverflowMode)
       
   670     {
       
   671         qreal step = mSpacing2D.width() + mImageSize2D.width();
       
   672         width -= (mRect.width() / step - 1.0f);
       
   673     }
   682        
   674        
   683     return width;
   675     return width;
   684 }
   676 }
   685 
   677 
   686 void HgMediaWallRenderer::beginRemoveRows(int start, int end)
   678 
   687 {
   679 void HgMediaWallRenderer::createAnimatedQuads(const HgAnimatedQuadFactory& factory)
   688     mRemoveStart = start;
   680 {
   689     mRemoveEnd = end;
       
   690     mItemCountChanged = true;
       
   691     
       
   692     recordState(mOldState);
       
   693 
       
   694 }
       
   695 
       
   696 void HgMediaWallRenderer::endRemoveRows()
       
   697 {
       
   698         
       
   699     mStateMachine->setAnimated(true);
       
   700 
       
   701     emit renderingNeeded();            
       
   702     
       
   703 }
       
   704 
       
   705 void HgMediaWallRenderer::startStateAnimation(QPainter* painter)
       
   706 {
       
   707     
       
   708     // clear previous animation quads
   681     // clear previous animation quads
   709     for (int i = 0; i < mAnimatedQuads.size(); i++)
   682     qDeleteAll(mAnimatedQuads.begin(), mAnimatedQuads.end());
   710     {
       
   711         delete mAnimatedQuads[i];
       
   712     }        
       
   713     mAnimatedQuads.clear();
   683     mAnimatedQuads.clear();
   714     
   684     
   715     // setup animated quads
   685     // default quad is used if no counterpart for the current quad exits.
   716     HgQuad* defaultQuad = new HgQuad();
   686     HgQuad* defaultQuad = new HgQuad();
   717     defaultQuad->setPosition(QVector3D(100,100,-100));
   687     defaultQuad->setPosition(QVector3D(100,100,-100));
   718     int n = mOldState.mQuads.count() < mNextState.mQuads.count() ? mNextState.mQuads.count() : mOldState.mQuads.count();
   688     
   719     for (int i = 0; i < n; i++)
   689     // setup new animated quads
   720     {
   690     QMap<int, HgQuad*>::iterator i = mNextState.mQuads.begin();
   721         HgQuad* qA = (i >= mOldState.mQuads.count()) ? defaultQuad : mOldState.mQuads[i];
   691     while(i != mNextState.mQuads.end())
   722         HgQuad* qB = (i >= mNextState.mQuads.count()) ? defaultQuad : mNextState.mQuads[i];
   692     {
   723         
   693         HgQuad* qB = i.value();
   724         HgAnimatedQuad* q = new HgAnimatedQuad(qA, qB, mStateAnimationDuration);
   694         HgQuad* qA = NULL;
       
   695         QMap<int, HgQuad*>::iterator j = mOldState.mQuads.find(i.key());
       
   696         if (j != mOldState.mQuads.end())
       
   697         {
       
   698             qA = j.value();
       
   699         }
       
   700         else
       
   701         {
       
   702             qA = defaultQuad->copy();
       
   703         }
       
   704         
       
   705         HgAnimatedQuad* q = factory.createQuad(qA, qB);
   725         mAnimatedQuads.append(q);
   706         mAnimatedQuads.append(q);
       
   707         
   726         q->start();
   708         q->start();
   727     }
   709         i++;
   728     
   710     }    
       
   711 }
       
   712 
       
   713 void HgMediaWallRenderer::startScrollDirectionChangeAnimation(
       
   714     const QPointF& startPosition,
       
   715     const QPointF& position, 
       
   716     const QPointF& targetPosition, 
       
   717     qreal springVelocity,
       
   718     QPainter* painter, 
       
   719     const QTransform& sceneTransform,
       
   720     const QRectF& rect)
       
   721 {
       
   722 
       
   723     // save state for current orientation
       
   724     setupRows(startPosition, position, targetPosition, springVelocity, painter);
       
   725     recordState(mOldState);
       
   726     
       
   727     // goto wanted orientation
       
   728     mScrollDirection = mNextScrollDirection;
       
   729     
       
   730     // setup quads to new state
       
   731     setupRows(startPosition, position, targetPosition, springVelocity, painter);
       
   732 
       
   733     // record state for animation
       
   734     recordState(mNextState);
       
   735     
       
   736     HgScrollDirChangeQuadFactory factory;
       
   737     factory.setup(mNextScrollDirection, mRect, mSpacing3D, mImageSize3D, mStateAnimationDuration);
       
   738 
       
   739     createAnimatedQuads(factory);
       
   740         
   729     mStateAnimationOnGoing = true;
   741     mStateAnimationOnGoing = true;
   730     
   742     
   731     // setup first frame of the animation
   743     // setup first frame of the animation
   732     setupStateAnimation(painter);        
   744     setupStateAnimation(painter);        
   733 
   745 
   734     // toggle state animation on
   746     // toggle state animation on
   735     toggleState();
   747     toggleState();
   736 
   748     
       
   749 }
       
   750 
       
   751 void HgMediaWallRenderer::startRowCountChangeAnimation(
       
   752     const QPointF& startPosition,
       
   753     const QPointF& position, 
       
   754     const QPointF& targetPosition, 
       
   755     qreal springVelocity,
       
   756     QPainter* painter, 
       
   757     const QTransform& sceneTransform,
       
   758     const QRectF& rect)
       
   759 {
       
   760     setupRows(startPosition, position, targetPosition, springVelocity, painter);
       
   761     recordState(mOldState);
       
   762     
       
   763     mRowCount = mNextRowCount;
       
   764     setImageSize(mNextImageSize);
       
   765     
       
   766     setupRows(startPosition, position, targetPosition, springVelocity, painter);
       
   767     recordState(mNextState);
       
   768 
       
   769     HgRowCountChangeQuadFactory factory(mStateAnimationDuration);    
       
   770 
       
   771     createAnimatedQuads(factory);
       
   772         
       
   773     mStateAnimationOnGoing = true;
       
   774     
       
   775     // setup first frame of the animation
       
   776     setupStateAnimation(painter);        
       
   777 
       
   778     // toggle state animation on
       
   779     toggleState();
   737 }
   780 }
   738 
   781 
   739 void HgMediaWallRenderer::setupCoverflow(const QPointF& startPosition,
   782 void HgMediaWallRenderer::setupCoverflow(const QPointF& startPosition,
   740     const QPointF& position, 
   783     const QPointF& position, 
   741     const QPointF& targetPosition, 
   784     const QPointF& targetPosition, 
   744 {   
   787 {   
   745     Q_UNUSED(startPosition)
   788     Q_UNUSED(startPosition)
   746     Q_UNUSED(targetPosition)
   789     Q_UNUSED(targetPosition)
   747     Q_UNUSED(springVelocity)
   790     Q_UNUSED(springVelocity)
   748     Q_UNUSED(painter)
   791     Q_UNUSED(painter)
   749     
   792         
   750     // save selected item for coverflow
       
   751     mSelectedItem = ceil(position.x());
       
   752     
       
   753     int quadsVisible = (mRect.width() / mImageSize2D.width() + 1) * 4;
   793     int quadsVisible = (mRect.width() / mImageSize2D.width() + 1) * 4;
   754     int selectedItemIndex = quadsVisible / 2;
   794     int selectedItemIndex = quadsVisible / 2;
   755 
   795 
   756     qreal step = mSpacing3D.width() + mImageSize3D.width();                
   796     qreal step = mSpacing3D.width() + mImageSize3D.width();                
   757     qreal ipos = floorf(position.x());
   797     qreal ipos = floorf(position.x());
   792         // modify z also for sorting
   832         // modify z also for sorting
   793         posZ -= 0.001f * abs(posX/step);
   833         posZ -= 0.001f * abs(posX/step);
   794                 
   834                 
   795         // setup quad for this item
   835         // setup quad for this item
   796         HgQuad* quad = mRenderer->quad(quadIndex);
   836         HgQuad* quad = mRenderer->quad(quadIndex);
   797         setupDefaultQuad(QVector3D(posX, posY, posZ), itemIndex, mReflectionsEnabled, quadIndex);
   837         setupDefaultQuad(QVector3D(posX, posY, posZ), itemIndex, reflectionsEnabled(), quadIndex);
   798                          
   838                          
   799         // step to next item                    
   839         // step to next item                    
   800         posX += step;        
   840         posX += step;        
   801         itemIndex++;
   841         itemIndex++;
   802         index++;
   842         index++;
   814     Q_UNUSED(startPosition)
   854     Q_UNUSED(startPosition)
   815     Q_UNUSED(targetPosition)
   855     Q_UNUSED(targetPosition)
   816     Q_UNUSED(springVelocity)
   856     Q_UNUSED(springVelocity)
   817     Q_UNUSED(painter)
   857     Q_UNUSED(painter)
   818     
   858     
   819     int rowCount = (mRect.height() / mImageSize2D.height() + 1) * 4;
   859     // we need to setup 2 times more rows than visible, because we need
   820     int rowsUp = rowCount/2;
   860     // more quads for the orientation switch
       
   861     int rowCount = (mRect.height() / mImageSize2D.height() + 1) * 3;       
       
   862     int rowsUp = rowCount / 3;
   821         
   863         
   822     qreal stepY = mSpacing3D.height() + mImageSize3D.height();
   864     qreal stepY = mSpacing3D.height() + mImageSize3D.height();
   823     qreal ipos = floorf(position.x());
   865     qreal ipos = floorf(position.x());
   824     qreal frac = (position.x() - ipos) * stepY;
   866     qreal frac = (position.x() - ipos) * stepY;
   825     qreal posY = -(qreal)rowsUp * stepY - frac;
   867     qreal posY = -(qreal)rowsUp * stepY - frac;
   826         
   868         
   827     // adjust height so that we begin from top
   869     // adjust height so that we begin from top
   828     qreal div = mRect.width() <= mRect.height() ? mRect.width() : mRect.height();
   870     posY -= mRect.height() / mRect.width() / 2.0 - stepY / 2.0;
   829     posY -= mRect.height() / div / 2.0 - stepY / 2.0;
       
   830     
   871     
   831     int count = mDataProvider->imageCount();
   872     int count = mDataProvider->imageCount();
   832     int itemIndex = ((int)(ipos - (qreal)rowsUp)) * mColumnCount;
   873     int itemIndex = ((int)(ipos - (qreal)rowsUp)) * mColumnCount;
   833     int row = 0;
   874     int row = 0;
   834     int quadIndex = 0;
   875     int quadIndex = 0;
   837     {
   878     {
   838         if (itemIndex < 0)
   879         if (itemIndex < 0)
   839         {
   880         {
   840             itemIndex+=mColumnCount;
   881             itemIndex+=mColumnCount;
   841             posY += stepY;
   882             posY += stepY;
   842             row++;
       
   843             continue;
   883             continue;
   844         }
   884         }
   845         else if (itemIndex >= count || quadIndex >= mRenderer->quadCount() || row >= rowCount)
   885         else if (itemIndex >= count || quadIndex >= mRenderer->quadCount() || row >= rowCount)
   846         {
   886         {
   847             break;
   887             break;
   849         
   889         
   850         setupGridRow(-posY, itemIndex, quadIndex);
   890         setupGridRow(-posY, itemIndex, quadIndex);
   851                         
   891                         
   852         posY += stepY;
   892         posY += stepY;
   853         row++;
   893         row++;
   854         itemIndex+=mColumnCount;
       
   855     }
   894     }
   856     
   895     
   857 }
   896 }
   858 
   897 
   859 void HgMediaWallRenderer::setupGridLandscape(const QPointF& startPosition,
   898 void HgMediaWallRenderer::setupGridLandscape(const QPointF& startPosition,
   864 {
   903 {
   865     Q_UNUSED(startPosition)
   904     Q_UNUSED(startPosition)
   866     Q_UNUSED(targetPosition)
   905     Q_UNUSED(targetPosition)
   867     Q_UNUSED(springVelocity)
   906     Q_UNUSED(springVelocity)
   868     Q_UNUSED(painter)
   907     Q_UNUSED(painter)
   869     
   908         
   870     int colCount = (mRect.width() / mImageSize2D.width() + 1) * 3;
   909     int colCount = (mRect.width() / mImageSize2D.width() + 1) * 3;
   871     int colsLeft = colCount/2;
   910     int colsLeft = colCount / 3;
   872 
   911 
   873     qreal stepX = mSpacing3D.width() + mImageSize3D.width();
   912     qreal stepX = mSpacing3D.width() + mImageSize3D.width();
   874     qreal ipos = floorf(position.x());
   913     qreal ipos = floorf(position.x());
   875     qreal frac = (position.x() - ipos) * stepX;
   914     qreal frac = (position.x() - ipos) * stepX;
   876     qreal posX = -(qreal)colsLeft * stepX - frac;    
   915     qreal posX = -(qreal)colsLeft * stepX - frac;    
   877     
   916     
       
   917     posX -= 0.5f - stepX / 2.0;
       
   918 
   878     int count = mDataProvider->imageCount();
   919     int count = mDataProvider->imageCount();
   879     int itemIndex = ((int)(ipos - (qreal)colsLeft)) * mRowCount;
   920     int itemIndex = ((int)(ipos - (qreal)colsLeft)) * mRowCount;
   880     int col = 0;
   921     int col = 0;
   881     int quadIndex = 0;
   922     int quadIndex = 0;
   882     
   923     
   884     {
   925     {
   885         if (itemIndex < 0)
   926         if (itemIndex < 0)
   886         {
   927         {
   887             itemIndex+=mColumnCount;
   928             itemIndex+=mColumnCount;
   888             posX += stepX;
   929             posX += stepX;
   889             col++;
       
   890             continue;
   930             continue;
   891         }
   931         }
   892         else if (itemIndex >= count || col >= colCount || quadIndex >= mRenderer->quadCount())
   932         else if (itemIndex >= count || col >= colCount || quadIndex >= mRenderer->quadCount())
   893         {
   933         {
   894             break;
   934             break;
   896         
   936         
   897         setupGridColumn(posX, itemIndex, quadIndex);
   937         setupGridColumn(posX, itemIndex, quadIndex);
   898                         
   938                         
   899         posX += stepX;
   939         posX += stepX;
   900         col++;
   940         col++;
   901         itemIndex+=mRowCount;
   941     }
   902     }
   942 }
   903 }
   943 
   904 
   944 void HgMediaWallRenderer::setupGridColumn(qreal posX, int& itemIndex, int& quadIndex)
   905 void HgMediaWallRenderer::setupGridColumn(qreal posX, int itemIndex, int& quadIndex)
       
   906 {
   945 {
   907     for (int i = 0; i < mRowCount; i++)
   946     for (int i = 0; i < mRowCount; i++)
   908     {
   947     {
       
   948         if (quadIndex >= mRenderer->quadCount() || itemIndex >= mDataProvider->imageCount())
       
   949             return;
       
   950         
   909         qreal posY = getRowPosY(i);
   951         qreal posY = getRowPosY(i);
   910         
   952         
   911         // enable reflections for the last row needed
   953         // enable reflections for the last row needed
   912         bool reflections = (i == (mRowCount-1) && mReflectionsEnabled);
   954         bool reflections = (i == (mRowCount-1) && reflectionsEnabled());
   913 
   955 
   914         setupDefaultQuad(QVector3D(posX, posY, 0), itemIndex++, reflections, quadIndex);
   956         setupDefaultQuad(QVector3D(posX, posY, 0), itemIndex++, reflections, quadIndex);
   915         
   957         
   916         if (itemIndex >= mDataProvider->imageCount())
       
   917             return;    
       
   918     }    
   958     }    
   919 }
   959 }
   920 
   960 
   921 void HgMediaWallRenderer::setupGridRow(qreal posY, int itemIndex, int& quadIndex)
   961 void HgMediaWallRenderer::setupGridRow(qreal posY, int& itemIndex, int& quadIndex)
   922 {
   962 {
   923     for (int i = 0; i < mColumnCount; i++)
   963     for (int i = 0; i < mColumnCount; i++)
   924     {
   964     {
       
   965         if (quadIndex >= mRenderer->quadCount() || itemIndex >= mDataProvider->imageCount())
       
   966             return;
       
   967 
   925         qreal posX = getColumnPosX(i);
   968         qreal posX = getColumnPosX(i);
       
   969 
   926         setupDefaultQuad(QVector3D(posX, posY, 0), itemIndex++, false, quadIndex);
   970         setupDefaultQuad(QVector3D(posX, posY, 0), itemIndex++, false, quadIndex);
   927         if (itemIndex >= mDataProvider->imageCount())
       
   928             return;     
       
   929     }    
   971     }    
   930 }
   972 }
   931 
   973 
   932 void HgMediaWallRenderer::setupDefaultQuad(const QVector3D& pos, int itemIndex, bool reflectionsEnabled, int& quadIndex)
   974 void HgMediaWallRenderer::setupDefaultQuad(const QVector3D& pos, int itemIndex, bool reflectionsEnabled, int& quadIndex)
   933 {
   975 {
   941     quad->setRotation(QQuaternion(1,0,0,0));
   983     quad->setRotation(QQuaternion(1,0,0,0));
   942     quad->setOuterRotation(QQuaternion(1,0,0,0));
   984     quad->setOuterRotation(QQuaternion(1,0,0,0));
   943     quad->enableMirrorImage(reflectionsEnabled);
   985     quad->enableMirrorImage(reflectionsEnabled);
   944     quad->setAlpha(1.0f);
   986     quad->setAlpha(1.0f);
   945     
   987     
   946     // apply opening animation if needed
       
   947  /*   if (itemIndex == mOpenedItem)
       
   948         applyOpeningAnimation(quad);
       
   949 */
       
   950     // setup indicator/decorator for the item if needed 
   988     // setup indicator/decorator for the item if needed 
   951     int flags = mDataProvider->flags(itemIndex);
   989     int flags = mDataProvider->flags(itemIndex);
   952     const HgImage* indicatorImage = mDataProvider->indicator(flags);
   990     const HgImage* indicatorImage = mDataProvider->indicator(flags);
   953     if (flags != 0 && indicatorImage)
   991     if (flags != 0 && indicatorImage && quadIndex < mRenderer->quadCount())
   954     {
   992     {
   955         HgQuad* indicator = mRenderer->quad(quadIndex++);
   993         HgQuad* indicator = mRenderer->quad(quadIndex++);
   956         setupIndicator(quad, indicator, indicatorImage, 
   994         setupIndicator(quad, indicator, indicatorImage, 
   957             itemIndex);
   995             itemIndex);
   958         indicator->enableMirrorImage(reflectionsEnabled);
   996         indicator->enableMirrorImage(reflectionsEnabled);
   974     indicator->setRotation(parent->rotation());
  1012     indicator->setRotation(parent->rotation());
   975     indicator->setOuterRotation(parent->outerRotation());
  1013     indicator->setOuterRotation(parent->outerRotation());
   976     indicator->enableMirrorImage(false);
  1014     indicator->enableMirrorImage(false);
   977     indicator->setAlpha(parent->alpha());
  1015     indicator->setAlpha(parent->alpha());
   978 
  1016 
   979     // apply opening animation to indicator if needed
       
   980     if (itemIndex == mOpenedItem)
       
   981         applyOpeningAnimation(indicator);
       
   982 }
  1017 }
   983 
  1018 
   984 HgQuadRenderer* HgMediaWallRenderer::getRenderer()
  1019 HgQuadRenderer* HgMediaWallRenderer::getRenderer()
   985 {
  1020 {
   986     return mRenderer;
  1021     return mRenderer;
   987 }
  1022 }
   988 
  1023 
   989 bool HgMediaWallRenderer::getItemPoints(int index, QPolygonF& points) const
  1024 bool HgMediaWallRenderer::getItemPoints(int index, QPolygonF& points) const
   990 {
  1025 {
   991     QPolygonF poly;
  1026     QPolygonF poly;
   992     if (!mRenderer->getQuadTranformedPoints(poly, index))
  1027     if (!mRenderer->getQuadTranformedPointsByUserData(poly, QVariant(index)))
   993         return false;
  1028         return false;
   994     
  1029     
   995     points = poly;
  1030     points = poly;
   996     return true;
  1031     return true;
   997 }
  1032 }
  1011 
  1046 
  1012 QPointF HgMediaWallRenderer::frontItemPosition() const
  1047 QPointF HgMediaWallRenderer::frontItemPosition() const
  1013 {
  1048 {
  1014     return mFrontItemPosition;
  1049     return mFrontItemPosition;
  1015 }
  1050 }
       
  1051 
       
  1052 void HgMediaWallRenderer::setOrientation(Qt::Orientation orientation)
       
  1053 {
       
  1054     mOrientation = orientation;
       
  1055 }