/*
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 .
*/
#include "KlondikeFlipStack.h"
#include "CardPixmaps.h"
#include
#include
const qreal KlondikeFlipStack::ExposedPrecent=.18;
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
KlondikeFlipStack::KlondikeFlipStack()
:CardStack(),
m_bRectVector(),
m_cardsShown(1),
m_firstShowCard(0)
{
}
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
KlondikeFlipStack::~KlondikeFlipStack()
{
}
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
QPointF KlondikeFlipStack::getGlobalCardAddPt() const
{
QPointF pt(0,0);
const PlayingCardVector & cardVector=this->getCardVector();
// We are going to do this by the bounding rects and not by actual cards
// in the stacks. That way we can add something before doing animations
// and then update the display when the animation is complete
if (m_bRectVector.size()>0 && cardVector.size()>=m_bRectVector.size())
{
pt=m_bRectVector[m_bRectVector.size()-1].topLeft();
pt.rx()+=this->getOverlapIncrement(cardVector,m_bRectVector.size()-1,m_firstShowCard);
}
return mapToScene(pt);
}
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
QPointF KlondikeFlipStack::getGlobalLastCardPt() const
{
QPointF pt(0,0);
const PlayingCardVector & cardVector=this->getCardVector();
// We are going to do this by the bounding rects and not by actual cards
// in the stacks. That way we can add something before doing animations
// and then update the display when the animation is complete
if (m_bRectVector.size()>0 && cardVector.size()>=m_bRectVector.size())
{
pt=m_bRectVector[m_bRectVector.size()-1].topLeft();
}
return mapToScene(pt);
}
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
QPointF KlondikeFlipStack::getGlobalCardPt(int index) const
{
QPointF pt(0,0);
if (index>=0 && index<(int)m_bRectVector.size())
{
pt=m_bRectVector[index].topLeft();
}
return mapToScene(pt);
}
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
void KlondikeFlipStack::updateStack()
{
PlayingCardVector cardVector=this->getCardVector();
m_bRectVector.clear();
// if the stack has no cards in it just call the base
// class to render the empty stack.
if (0==cardVector.size())
{
CardStack::updateStack();
return;
}
// figure out the index of the first card to show
if (m_cardsShown>=cardVector.size())
{
m_firstShowCard=0;
}
else
{
m_firstShowCard=cardVector.size()-m_cardsShown;
}
// now calc the size of the pixmap we will need
QSize pixmapSize;
this->calcPixmapSize(cardVector,pixmapSize,m_firstShowCard);
QPixmap pixmap(pixmapSize);
// for linux the transparent fill must be done before
// we associate the pixmap with the painter
pixmap.fill(Qt::transparent);
QPainter painter;
painter.begin(&pixmap);
QPoint pt(0,0);
QSize cardSize(CardPixmaps::getInst().getCardSize());
unsigned int i;
for (i=0;i=m_firstShowCard)
{
bool hl=((hintHighlightIndex()>=0 && hintHighlightIndex()<=(int)i) ||
((cardVector.size()-1==i) && isHighlighted()));
if (cardVector[i].isFaceUp())
{
painter.drawPixmap(pt,CardPixmaps::getInst().getCardPixmap(cardVector[i],hl));
}
else
{
painter.drawPixmap(pt,CardPixmaps::getInst().getCardBackPixmap(hl));
}
}
if (cardVector.size()-1==i)
{
m_bRectVector.push_back(QRectF(QPoint(pt.x(),0),
cardSize));
}
else
{
m_bRectVector.push_back(QRectF(QPoint(pt.x(),0),
QSize(incrementValue,cardSize.height())));
}
// increment the point that we are going to paint the
// card pixmap onto this pixmap
pt.rx()+=incrementValue;
}
painter.end();
this->setPixmap(pixmap);
}
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
bool KlondikeFlipStack::getCardIndex(const QPointF & pos,unsigned int & index)
{
bool rc=false;
unsigned int i;
// go through the bounding rect backwards. The ones lower for cards that are
// not visible are just place holders.
for(i=m_bRectVector.size();i>0;i--)
{
if (m_bRectVector[i-1].contains(pos))
{
index=i-1;
rc=true;
break;
}
}
return rc;
}
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
void KlondikeFlipStack::calcPixmapSize(const PlayingCardVector & cardVector,
QSize & size,unsigned int showIndex)
{
QSize cardSize(CardPixmaps::getInst().getCardSize());
unsigned int i;
size.setWidth(0);
size.setHeight(cardSize.height());
for(i=0;igetOverlapIncrement(cardVector,i,showIndex);
}
}
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
int KlondikeFlipStack::getOverlapIncrement(const PlayingCardVector & cardVector,
unsigned int index,unsigned int showIndex) const
{
int increment=0;
if (index=showIndex)
{
increment=CardPixmaps::getInst().getCardSize().width()*ExposedPrecent;
}
}
return increment;
}
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
bool KlondikeFlipStack::canMoveCard(unsigned int index) const
{
bool rc=false;
// ok the only time a card can be moved is if the card is the last in the stack.
if (!this->isEmpty() && (index==(this->getCardVector().size()-1)))
{
rc=true;
}
return rc;
}