[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    KDE/kdegames/kpat/libkcardgame
From:       Parker Coates <parker.coates () kdemail ! net>
Date:       2011-02-15 20:57:38
Message-ID: 20110215205738.DABBCAC8C3 () svn ! kde ! org
[Download RAW message or body]

SVN commit 1220946 by coates:

Add KCardScenePrivate::sendCardsToPile() to handle all card movements.

By using a single method for all card movement operations and pile
relayout animations removes a lot of hacks, like saving card positions,
doing an instant relayout, saving the new positions, returning the cards
to their original positions and then animating to the new positions.

 M  +124 -122  kcardscene.cpp  
 M  +5 -3      kcardscene.h  


--- trunk/KDE/kdegames/kpat/libkcardgame/kcardscene.cpp #1220945:1220946
@@ -68,7 +68,7 @@
 public:
     KCardScenePrivate( KCardScene * p );
 
-    int calculateDuration( QPointF pos1, QPointF pos2, qreal velocity ) const;
+    void sendCardsToPile( KCardPile * pile, QList<KCard*> cards, qreal rate, bool \
isSpeed, bool flip );  void changeFocus( int pileChange, int cardChange );
     void updateKeyboardFocus();
 
@@ -105,17 +105,103 @@
 }
 
 
-int KCardScenePrivate::calculateDuration( QPointF pos1, QPointF pos2, qreal velocity \
) const +void KCardScenePrivate::sendCardsToPile( KCardPile * pile, QList<KCard*> \
newCards, qreal rate, bool isSpeed, bool flip )  {
-    QPointF delta = pos2 - pos1;
-    qreal distance = sqrt( delta.x() * delta.x() + delta.y() * delta.y() );
-    qreal cardUnit = ( deck->cardWidth() + deck->cardHeight() ) / 2.0;
-    qreal unitDistance = distance / cardUnit;
+    if ( pile->isEmpty() && newCards.isEmpty() )
+        return;
 
-    return 1000 * unitDistance / velocity;
+    const QList<KCard*> oldCards = pile->cards();
+
+    foreach ( KCard * c, newCards )
+    {
+        pile->add( c );
+        if ( flip )
+            c->setFaceUp( !c->isFaceUp() );
+        c->raise();
 }
 
+    const QSize cardSize = deck->cardSize();
+    const qreal cardUnit = (deck->cardWidth() + deck->cardHeight()) / 2.0;
+    const QList<KCard*> allCards = pile->cards();
+    const QList<QPointF> positions = pile->cardPositions();
 
+    qreal minX = 0;
+    qreal maxX = 0;
+    qreal minY = 0;
+    qreal maxY = 0;
+    foreach ( const QPointF & pos, positions )
+    {
+        minX = qMin( minX, pos.x() );
+        maxX = qMax( maxX, pos.x() );
+        minY = qMin( minY, pos.y() );
+        maxY = qMax( maxY, pos.y() );
+    }
+
+    QPointF absLayoutPos = pile->layoutPos();
+    if ( absLayoutPos.x() < 0 )
+        absLayoutPos.rx() += contentSize.width() / cardSize.width() - 1;
+    if ( absLayoutPos.y() < 0 )
+        absLayoutPos.ry() += contentSize.height() / cardSize.height() - 1;
+
+    QRectF available = pileAreas.value( pile, QRectF() );
+    qreal availableTop = absLayoutPos.y() - available.top();
+    qreal availableBottom = available.bottom() - (absLayoutPos.y() + 1);
+    qreal availableLeft = absLayoutPos.x() - available.left();
+    qreal availableRight = available.right() - (absLayoutPos.x() + 1);
+
+    qreal scaleTop = (minY >= 0) ? 1 : qMin<qreal>( availableTop / -minY, 1 );
+    qreal scaleBottom = (maxY <= 0) ? 1 : qMin<qreal>( availableBottom / maxY, 1 );
+    qreal scaleY = qMin( scaleTop, scaleBottom );
+
+    qreal scaleLeft = (minX >= 0) ? 1 : qMin<qreal>( availableLeft / -minX, 1 );
+    qreal scaleRight = (maxX <= 0) ? 1 : qMin<qreal>( availableRight / maxX, 1 );
+    qreal scaleX = qMin( scaleLeft, scaleRight );
+
+    qreal z = pile->zValue();
+
+    QList<QPointF> realPositions;
+    QList<qreal> distances;
+    qreal maxDistance = 0;
+    for ( int i = 0; i < allCards.size(); ++i )
+    {
+        QPointF pos( pile->x() + positions[i].x() * scaleX * cardSize.width(),
+                     pile->y() + positions[i].y() * scaleY * cardSize.height() );
+        realPositions << pos;
+
+        qreal distance = 0;
+        if ( isSpeed && i >= oldCards.size() )
+        {
+            QPointF delta = pos - allCards[i]->pos();
+            distance = sqrt( delta.x() * delta.x() + delta.y() * delta.y() ) / \
cardUnit; +            if ( distance > maxDistance )
+                maxDistance = distance;
+        }
+        distances << distance;
+    }
+
+    int layoutDuration = isSpeed ? qMin<int>( cardMoveDuration, maxDistance / rate * \
1000 ) : rate; +
+    for ( int i = 0; i < allCards.size(); ++i )
+    {
+        bool face = allCards[i]->isFaceUp();
+        int duration = layoutDuration;
+        if ( i < oldCards.size() )
+        {
+            face = face || (allCards[i] == pile->top() && pile->autoTurnTop());
+        }
+        else
+        {
+            if ( flip )
+                allCards[i]->setFaceUp( !allCards[i]->isFaceUp() );
+            if ( isSpeed )
+                duration = distances[i] / rate * 1000;
+        }
+        ++z;
+        allCards[i]->animate( realPositions[i], z, 0, face, false, duration );
+    }
+}
+
+
 void KCardScenePrivate::changeFocus( int pileChange, int cardChange )
 {
     if ( !keyboardMode )
@@ -645,22 +731,14 @@
 }
 
 
-void KCardScene::moveCardsToPile( QList<KCard*> cards, KCardPile * pile, int \
duration ) +void KCardScene::moveCardsToPile( const QList<KCard*> & cards, KCardPile \
* pile, int duration )  {
     if ( cards.isEmpty() )
         return;
 
     KCardPile * source = cards.first()->pile();
-
-    foreach ( KCard * c, cards )
-    {
-        Q_ASSERT( c->pile() == source );
-        pile->add( c );
-        c->raise();
-    }
-
-    updatePileLayout( source, duration );
-    updatePileLayout( pile, duration );
+    d->sendCardsToPile( pile, cards, duration, false, false );
+    d->sendCardsToPile( source, QList<KCard*>(), duration, false, false );
     cardsMoved( cards, source, pile );
 }
 
@@ -671,61 +749,34 @@
 }
 
 
-void KCardScene::moveCardToPileAtSpeed( KCard * card, KCardPile * pile, qreal \
velocity ) +void KCardScene::moveCardsToPileAtSpeed( const QList<KCard*> & cards, \
KCardPile * pile, qreal velocity )  {
-    QPointF origPos = card->pos();
+    if ( cards.isEmpty() )
+        return;
 
-    QPointF estimatedDestPos = pile->isEmpty() ? pile->pos() : pile->top()->pos();
-    moveCardToPile( card, pile, d->calculateDuration( origPos, estimatedDestPos, \
                velocity ) );
-
-    card->completeAnimation();
-    QPointF destPos = card->pos();
-    card->setPos( origPos );
-
-    int duration = d->calculateDuration( origPos, destPos, velocity );
-    card->animate( destPos, card->zValue(), 0, card->isFaceUp(), true, duration );
+    KCardPile * source = cards.first()->pile();
+    d->sendCardsToPile( pile, cards, velocity, true, false );
+    d->sendCardsToPile( source, QList<KCard*>(), cardMoveDuration, false, false );
+    cardsMoved( cards, source, pile );
 }
 
 
-void KCardScene::flipCardsToPile( QList<KCard*> cards, KCardPile * pile, int \
duration ) +void KCardScene::moveCardToPileAtSpeed( KCard * card, KCardPile * pile, \
qreal velocity )  {
-    QList<KCard*> revCards;
-    QList<bool> origFaces;
-    QList<QPointF> origPositions;
-    QList<qreal> origZValues;
-
-    for ( int i = cards.size() - 1; i >= 0; --i )
-    {
-        KCard * c = cards.at( i );
-        revCards << c;
-        origFaces << c->isFaceUp();
-        origZValues << c->zValue();
-        origPositions << c->pos();
-
-        c->setFaceUp( !c->isFaceUp() );
+    moveCardsToPileAtSpeed( QList<KCard*>() << card, pile, velocity );
     }
 
-    moveCardsToPile( revCards, pile, duration );
 
-    for ( int i = 0; i < revCards.size(); ++i )
+void KCardScene::flipCardsToPile( const QList<KCard*> & cards, KCardPile * pile, int \
duration )  {
-        KCard * c = revCards.at( i );
+    if ( cards.isEmpty() )
+        return;
 
-        c->completeAnimation();
-        c->setFaceUp( origFaces.at( i ) );
-        QPointF destPos = c->pos();
-        c->setPos( origPositions.at( i ) );
-        qreal destZValue = c->zValue();
-
-        // This is a bit of a hack. It means we preserve the z ordering of face
-        // up cards, but feel free to mess about with face down ones. This may
-        // need to be smarter in the future.
-        if ( c->isFaceUp() )
-            c->setZValue( origZValues.at( i ) );
-
-        c->animate( destPos, destZValue, 0, !c->isFaceUp(), true, duration );
+    KCardPile * source = cards.first()->pile();
+    d->sendCardsToPile( pile, cards, duration, false, true );
+    d->sendCardsToPile( source, QList<KCard*>(), duration, false, false );
+    cardsMoved( cards, source, pile );
     }
-}
 
 
 void KCardScene::flipCardToPile( KCard * card, KCardPile * pile, int duration )
@@ -734,22 +785,21 @@
 }
 
 
-void KCardScene::flipCardToPileAtSpeed( KCard * card, KCardPile * pile, qreal \
velocity ) +void KCardScene::flipCardsToPileAtSpeed( const QList<KCard*> & cards, \
KCardPile * pile, qreal velocity )  {
-    QPointF origPos = card->pos();
-    bool origFaceUp = card->isFaceUp();
+    if ( cards.isEmpty() )
+        return;
 
-    QPointF estimatedDestPos = pile->isEmpty() ? pile->pos() : pile->top()->pos();
-    card->setFaceUp( !origFaceUp );
-    moveCardToPile( card, pile, d->calculateDuration( origPos, estimatedDestPos, \
velocity ) ); +    KCardPile * source = cards.first()->pile();
+    d->sendCardsToPile( pile, cards, velocity, true, true );
+    d->sendCardsToPile( source, QList<KCard*>(), cardMoveDuration, false, false );
+    cardsMoved( cards, source, pile );
+}
 
-    card->completeAnimation();
-    QPointF destPos = card->pos();
-    card->setPos( origPos );
-    card->setFaceUp( origFaceUp );
 
-    int duration = d->calculateDuration( origPos, destPos, velocity );
-    card->animate( destPos, card->zValue(), 0, !origFaceUp, true, duration );
+void KCardScene::flipCardToPileAtSpeed( KCard * card, KCardPile * pile, qreal \
velocity ) +{
+    flipCardsToPileAtSpeed( QList<KCard*>() << card, pile, velocity );
 }
 
 
@@ -889,58 +939,10 @@
 
 void KCardScene::updatePileLayout( KCardPile * pile, int duration )
 {
-    if ( pile->isEmpty() )
-        return;
-
-    const QSize cardSize = d->deck->cardSize();
-    const QList<KCard*> cards = pile->cards();
-    const QList<QPointF> positions = pile->cardPositions();
-
-    qreal minX = 0;
-    qreal maxX = 0;
-    qreal minY = 0;
-    qreal maxY = 0;
-    foreach ( const QPointF & pos, positions )
-    {
-        minX = qMin( minX, pos.x() );
-        maxX = qMax( maxX, pos.x() );
-        minY = qMin( minY, pos.y() );
-        maxY = qMax( maxY, pos.y() );
+    d->sendCardsToPile( pile, QList<KCard*>(), duration, false, false );
     }
 
-    QPointF absLayoutPos = pile->layoutPos();
-    if ( absLayoutPos.x() < 0 )
-        absLayoutPos.rx() += contentArea().width() / cardSize.width() - 1;
-    if ( absLayoutPos.y() < 0 )
-        absLayoutPos.ry() += contentArea().height() / cardSize.height() - 1;
 
-    QRectF available = d->pileAreas.value( pile, QRectF() );
-    qreal availableTop = absLayoutPos.y() - available.top();
-    qreal availableBottom = available.bottom() - (absLayoutPos.y() + 1);
-    qreal availableLeft = absLayoutPos.x() - available.left();
-    qreal availableRight = available.right() - (absLayoutPos.x() + 1);
-
-    qreal scaleTop = (minY >= 0) ? 1 : qMin<qreal>( availableTop / -minY, 1 );
-    qreal scaleBottom = (maxY <= 0) ? 1 : qMin<qreal>( availableBottom / maxY, 1 );
-    qreal scaleY = qMin( scaleTop, scaleBottom );
-
-    qreal scaleLeft = (minX >= 0) ? 1 : qMin<qreal>( availableLeft / -minX, 1 );
-    qreal scaleRight = (maxX <= 0) ? 1 : qMin<qreal>( availableRight / maxX, 1 );
-    qreal scaleX = qMin( scaleLeft, scaleRight );
-
-    qreal z = pile->zValue();
-
-    for ( int i = 0; i < cards.size(); ++i )
-    {
-        QPointF pos( pile->x() + positions[i].x() * scaleX * cardSize.width(),
-                     pile->y() + positions[i].y() * scaleY * cardSize.height() );
-        bool face = cards[i]->isFaceUp() || (cards[i] == pile->top() && \
                pile->autoTurnTop());
-        ++z;
-        cards[i]->animate( pos, z, 0, face, false, duration );
-    }
-}
-
-
 bool KCardScene::allowedToAdd( const KCardPile * pile, const QList<KCard*> & cards ) \
const  {
     Q_UNUSED( pile )
--- trunk/KDE/kdegames/kpat/libkcardgame/kcardscene.h #1220945:1220946
@@ -94,12 +94,15 @@
     void clearHighlightedItems();
     QList<QGraphicsItem*> highlightedItems() const;
 
-    void moveCardsToPile( QList<KCard*> cards, KCardPile * pile, int duration );
+    void moveCardsToPile( const QList<KCard*> & cards, KCardPile * pile, int \
duration );  void moveCardToPile( KCard * card, KCardPile * pile, int duration );
+    void moveCardsToPileAtSpeed( const QList<KCard*> & cards, KCardPile * pile, \
                qreal velocity );
     void moveCardToPileAtSpeed( KCard * card, KCardPile * pile, qreal velocity );
-    void flipCardsToPile( QList<KCard*> cards, KCardPile * pile, int duration );
+    void flipCardsToPile( const QList<KCard*> & cards, KCardPile * pile, int \
duration );  void flipCardToPile( KCard * card, KCardPile * pile, int duration );
+    void flipCardsToPileAtSpeed( const QList<KCard*> & cards, KCardPile * pile, \
                qreal velocity );
     void flipCardToPileAtSpeed( KCard * card, KCardPile * pile, qreal velocity );
+    void updatePileLayout( KCardPile * pile, int duration );
 
     bool isCardAnimationRunning() const;
 
@@ -131,7 +134,6 @@
     virtual bool allowedToRemove( const KCardPile * pile, const KCard * card ) \
const;  virtual KCardPile * targetPile();
 
-    void updatePileLayout( KCardPile * pile, int duration );
     virtual void cardsDroppedOnPile( const QList<KCard*> & cards, KCardPile * pile \
                );
     virtual void cardsMoved( const QList<KCard*> & cards, KCardPile * oldPile, \
KCardPile * newPile );  


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic