[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