mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
335 lines
8.8 KiB
C++
335 lines
8.8 KiB
C++
|
/*
|
||
|
QSoloCards is a collection of Solitaire card games written using Qt
|
||
|
Copyright (C) 2009 Steve Moore
|
||
|
|
||
|
This program is free software: you can redistribute it and/or modify
|
||
|
it under the terms of the GNU General Public License as published by
|
||
|
the Free Software Foundation, either version 3 of the License, or
|
||
|
(at your option) any later version.
|
||
|
|
||
|
This program is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
#include "StackToStackFlipAni.h"
|
||
|
#include "CardAnimationLock.h"
|
||
|
#include "CardPixmaps.h"
|
||
|
|
||
|
#include <QtGui/QGraphicsScene>
|
||
|
#include <QtGui/QPainter>
|
||
|
|
||
|
#include <iostream>
|
||
|
|
||
|
const qreal StackToStackFlipAni::ExposedPrecentShownCards=.18;
|
||
|
const qreal StackToStackFlipAni::ExposedPrecentHiddenCards=.02;
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||
|
StackToStackFlipAni::StackToStackFlipAni()
|
||
|
:m_pDst(NULL),
|
||
|
m_pSrc(NULL),
|
||
|
m_cardVector(),
|
||
|
m_firstCardToShow(0),
|
||
|
m_flipPtReached(false),
|
||
|
m_moveRecord(),
|
||
|
m_pTimeLine(NULL),
|
||
|
m_pItemAni(NULL),
|
||
|
m_pPixmapItem(NULL),
|
||
|
m_aniRunning(false)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||
|
StackToStackFlipAni::~StackToStackFlipAni()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||
|
void StackToStackFlipAni::moveCards(CardStack * pDst,CardStack * pSrc,
|
||
|
int numCards,int cardsShown,
|
||
|
int duration)
|
||
|
{
|
||
|
// first if we have an animation running stop it.
|
||
|
this->stopAni();
|
||
|
|
||
|
// setup the next animation.
|
||
|
m_pDst=pDst;
|
||
|
m_pSrc=pSrc;
|
||
|
m_cardVector.clear();
|
||
|
m_moveRecord.clear();
|
||
|
m_flipPtReached=false;
|
||
|
|
||
|
while( !m_pSrc->isEmpty() && numCards>0)
|
||
|
{
|
||
|
PlayingCard card(m_pSrc->removeTopCard(m_moveRecord));
|
||
|
|
||
|
m_cardVector.insert(m_cardVector.begin(),card);
|
||
|
numCards--;
|
||
|
}
|
||
|
|
||
|
// by default we will show all cards
|
||
|
m_firstCardToShow=0;
|
||
|
|
||
|
// if we are not showing all cards starting with index 0
|
||
|
// then figure out the index of the first card that will
|
||
|
// be shown.
|
||
|
if (m_cardVector.size()>0 && cardsShown>=0 &&
|
||
|
cardsShown<(int)m_cardVector.size())
|
||
|
{
|
||
|
// ok if the value is 0 or 1. We will just show
|
||
|
// the last card. 0 doesn't make any sense if you
|
||
|
// are flipping cards. So, we will assume one for
|
||
|
// that case as well.
|
||
|
if (cardsShown<=1)
|
||
|
{
|
||
|
m_firstCardToShow=m_cardVector.size()-1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_firstCardToShow=m_cardVector.size()-cardsShown;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
// if animation is off just immediately add the cards to the new
|
||
|
// stack. Call updateStack to redraw the stacks. And emit the
|
||
|
// signal that the cards have been moved.
|
||
|
if (!CardAnimationLock::getInst().animationsEnabled())
|
||
|
{
|
||
|
this->flipCards();
|
||
|
m_pSrc->updateStack();
|
||
|
|
||
|
m_pDst->addCards(m_cardVector,m_moveRecord);
|
||
|
m_pDst->updateStack();
|
||
|
emit cardsMoved(m_moveRecord);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CardAnimationLock::getInst().lock();
|
||
|
runAnimation(duration);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||
|
void StackToStackFlipAni::slotAniFinished(bool emitSignal)
|
||
|
{
|
||
|
if (m_aniRunning)
|
||
|
{
|
||
|
m_aniRunning=false;
|
||
|
this->m_pTimeLine->stop();
|
||
|
|
||
|
m_pDst->addCards(m_cardVector,m_moveRecord);
|
||
|
m_pDst->updateStack();
|
||
|
|
||
|
// remove the animation object
|
||
|
m_pSrc->scene()->removeItem(m_pPixmapItem);
|
||
|
delete m_pPixmapItem;
|
||
|
m_pPixmapItem=NULL;
|
||
|
|
||
|
CardAnimationLock::getInst().unlock();
|
||
|
|
||
|
if (emitSignal)
|
||
|
{
|
||
|
emit cardsMoved(m_moveRecord);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||
|
void StackToStackFlipAni::slotAniProgress(qreal currProgress)
|
||
|
{
|
||
|
if (currProgress>=.6 && !m_flipPtReached)
|
||
|
{
|
||
|
m_flipPtReached=true;
|
||
|
|
||
|
this->flipCards();
|
||
|
|
||
|
QPixmap * pPixmap=this->getAniPixmap();
|
||
|
|
||
|
if (pPixmap)
|
||
|
{
|
||
|
m_pPixmapItem->setPixmap(*pPixmap);
|
||
|
delete pPixmap;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||
|
void StackToStackFlipAni::runAnimation(int duration)
|
||
|
{
|
||
|
m_aniRunning=true;
|
||
|
|
||
|
delete m_pTimeLine;
|
||
|
delete m_pItemAni;
|
||
|
delete m_pPixmapItem;
|
||
|
|
||
|
|
||
|
m_pTimeLine=new QTimeLine(duration);
|
||
|
m_pItemAni=new QGraphicsItemAnimation;
|
||
|
m_pPixmapItem=new QGraphicsPixmapItem;
|
||
|
|
||
|
|
||
|
QPixmap * pPixmap=this->getAniPixmap();
|
||
|
|
||
|
if (pPixmap)
|
||
|
{
|
||
|
m_pPixmapItem->setPixmap(*pPixmap);
|
||
|
delete pPixmap;
|
||
|
}
|
||
|
|
||
|
// set the z value to 2 so it will be on top of the
|
||
|
// stacks.
|
||
|
m_pPixmapItem->setZValue(2);
|
||
|
|
||
|
// add the item to the scene and move it over the stack in the
|
||
|
// place of the cards we are going to move
|
||
|
m_pSrc->scene()->addItem(m_pPixmapItem);
|
||
|
m_pPixmapItem->setPos(m_pSrc->getGlobalLastCardPt());
|
||
|
|
||
|
|
||
|
// setup the animation
|
||
|
m_pItemAni->setItem(m_pPixmapItem);
|
||
|
m_pItemAni->setTimeLine(m_pTimeLine);
|
||
|
|
||
|
// set the start and end point
|
||
|
m_pItemAni->setPosAt (0, m_pSrc->getGlobalLastCardPt());
|
||
|
m_pItemAni->setPosAt (1, m_pDst->getGlobalCardAddPt());
|
||
|
|
||
|
// set the scaling to give the flipping effect.
|
||
|
m_pItemAni->setScaleAt( 0, 1, 1 );
|
||
|
m_pItemAni->setScaleAt( 0.6, 0, 1 );
|
||
|
m_pItemAni->setScaleAt( 1, 1, 1 );
|
||
|
|
||
|
// connect up the slot so we will know when it is finished.
|
||
|
this->connect(m_pTimeLine,SIGNAL(finished()),
|
||
|
this,SLOT(slotAniFinished()));
|
||
|
|
||
|
this->connect(m_pTimeLine,SIGNAL(valueChanged(qreal)),
|
||
|
this,SLOT(slotAniProgress(qreal)));
|
||
|
|
||
|
// update the src stack behind the flip item we just added
|
||
|
m_pSrc->updateStack();
|
||
|
|
||
|
m_pTimeLine->start();
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||
|
QPixmap * StackToStackFlipAni::getAniPixmap()
|
||
|
{
|
||
|
QPixmap * pPixmap=NULL;
|
||
|
|
||
|
if (m_cardVector.size()>0)
|
||
|
{
|
||
|
unsigned int i;
|
||
|
|
||
|
pPixmap =new QPixmap(this->calcPixmapSize());
|
||
|
// for linux the transparent fill must be done before
|
||
|
// we associate the pixmap with the painter
|
||
|
pPixmap->fill(Qt::transparent);
|
||
|
|
||
|
QPainter painter(pPixmap);
|
||
|
|
||
|
|
||
|
QPoint pt(0,0);
|
||
|
|
||
|
for (i=0;i<m_cardVector.size();i++)
|
||
|
{
|
||
|
if (m_cardVector[i].isFaceUp())
|
||
|
{
|
||
|
painter.drawPixmap(pt,CardPixmaps::getInst().getCardPixmap(m_cardVector[i]));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
painter.drawPixmap(pt,CardPixmaps::getInst().getCardBackPixmap());
|
||
|
}
|
||
|
|
||
|
pt.rx()+=getOverlapIncrement(i);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pPixmap=new QPixmap(CardPixmaps::getInst().getTransparentPixmap());
|
||
|
}
|
||
|
|
||
|
return pPixmap;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||
|
QSize StackToStackFlipAni::calcPixmapSize()
|
||
|
{
|
||
|
QSize cardSize(CardPixmaps::getInst().getCardSize());
|
||
|
QSize size(0,cardSize.height());
|
||
|
|
||
|
unsigned int i;
|
||
|
|
||
|
for(i=0;i<m_cardVector.size();i++)
|
||
|
{
|
||
|
if (m_cardVector.size()-1==i)
|
||
|
{
|
||
|
size.rwidth()+=cardSize.width();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
size.rwidth()+=getOverlapIncrement(i);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return size;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||
|
int StackToStackFlipAni::getOverlapIncrement(unsigned int index)
|
||
|
{
|
||
|
int increment=0;
|
||
|
|
||
|
if (index<m_cardVector.size())
|
||
|
{
|
||
|
if (index>=m_firstCardToShow && m_cardVector[index].isFaceUp())
|
||
|
{
|
||
|
increment=CardPixmaps::getInst().getCardSize().width()*ExposedPrecentShownCards;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
increment=CardPixmaps::getInst().getCardSize().width()*ExposedPrecentHiddenCards;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return increment;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||
|
void StackToStackFlipAni::flipCards()
|
||
|
{
|
||
|
|
||
|
if (m_cardVector.size()>0)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
PlayingCardVector flipVector;
|
||
|
|
||
|
for(i=m_cardVector.size()-1;i>=0;i--)
|
||
|
{
|
||
|
m_cardVector[i].setFaceUp(!m_cardVector[i].isFaceUp());
|
||
|
flipVector.push_back(m_cardVector[i]);
|
||
|
}
|
||
|
|
||
|
m_cardVector.clear();
|
||
|
m_cardVector=flipVector;
|
||
|
}
|
||
|
}
|