mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-11 00:44:27 -05:00
239 lines
10 KiB
C
239 lines
10 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/>.
|
||
|
*/
|
||
|
|
||
|
#ifndef CARDSTACK_H
|
||
|
#define CARDSTACK_H
|
||
|
|
||
|
#include <QtCore/QObject>
|
||
|
#include <QtGui/QGraphicsPixmapItem>
|
||
|
|
||
|
#include "CardMoveRecord.h"
|
||
|
|
||
|
#include "FlipAnimation.h"
|
||
|
#include "DragCardStack.h"
|
||
|
|
||
|
#include <map>
|
||
|
#include <string>
|
||
|
|
||
|
class CardStack;
|
||
|
|
||
|
typedef std::map<std::string,CardStack *> CardStackMap;
|
||
|
|
||
|
|
||
|
class CardStack: public QObject,public QGraphicsPixmapItem
|
||
|
{
|
||
|
Q_OBJECT
|
||
|
public:
|
||
|
enum ProcessCardMoveRecordType
|
||
|
{
|
||
|
UndoMove=0,
|
||
|
RedoMove=1
|
||
|
};
|
||
|
|
||
|
enum
|
||
|
{
|
||
|
HintHighlightNoCards=-2
|
||
|
};
|
||
|
|
||
|
CardStack();
|
||
|
virtual ~CardStack();
|
||
|
|
||
|
inline const std::string stackName()const{return m_stackName.toStdString();}
|
||
|
|
||
|
inline bool isFlipAniRunning()const {return m_flipAni.isAniRunning();}
|
||
|
|
||
|
|
||
|
bool allCardsFaceUp()const;
|
||
|
|
||
|
// top is in this case the last card in the stack. bottom is index 0
|
||
|
bool cardsAscendingTopToBottom()const;
|
||
|
bool cardsDecendingTopToBottom()const;
|
||
|
|
||
|
void setTopCardUp(bool faceUp=true);
|
||
|
|
||
|
bool flipCard(int index,bool aniIfEnabled=true);
|
||
|
bool flipCard(int index,CardMoveRecord & moveRecord,bool aniIfEnabled=true);
|
||
|
|
||
|
inline void setAutoTopCardUp(bool autoFaceUp=true){this->m_autoFaceUp=autoFaceUp;}
|
||
|
inline bool isAutoTopCardUp()const {return m_autoFaceUp;}
|
||
|
|
||
|
|
||
|
inline bool isHighlighted() const {return m_highlighted;}
|
||
|
inline void setHighlighted(bool state=true){m_highlighted=state;}
|
||
|
|
||
|
inline int hintHighlightIndex() const {return m_hintHighlightIndex;}
|
||
|
|
||
|
|
||
|
inline bool showRedealCircle(){return m_showRedealCircle;}
|
||
|
inline void setShowRedealCircle(bool state=true){m_showRedealCircle=state;}
|
||
|
|
||
|
void addCard(const PlayingCard & newCard);
|
||
|
void addCards(const PlayingCardVector & cardVector);
|
||
|
|
||
|
void addCard(const PlayingCard & newCard,CardMoveRecord & moveRecord,bool justUpdateRec=false);
|
||
|
void addCards(const PlayingCardVector & cardVector,CardMoveRecord & moveRecord,bool justUpdateRec=false);
|
||
|
|
||
|
|
||
|
// pull the top card off of the stack
|
||
|
PlayingCard removeTopCard();
|
||
|
PlayingCard removeTopCard(CardMoveRecord & moveRecord);
|
||
|
|
||
|
// the cardVector contains the cards that were removed if the index is valid.
|
||
|
bool removeCardsStartingAt(unsigned int index,PlayingCardVector & removedCards);
|
||
|
bool removeCardsStartingAt(unsigned int index,PlayingCardVector & removedCards,
|
||
|
CardMoveRecord & moveRecord,bool justUpdateRec=false);
|
||
|
|
||
|
void removeAllCards();
|
||
|
|
||
|
inline bool isEmpty() const {return m_cardVector.empty();}
|
||
|
|
||
|
const PlayingCardVector & getCardVector()const{return m_cardVector;}
|
||
|
|
||
|
virtual bool canAddCards(const PlayingCardVector &){return false;}
|
||
|
|
||
|
// this function will return the cards at the end of the stack that can be moved.
|
||
|
// the function canMoveCards that can be overridden by subclasses controls the
|
||
|
// cards that can be moved. This function can also be overridden if something other
|
||
|
// than the default of just cards at the end of the stack is desired.
|
||
|
//
|
||
|
// the cards that can be moved will be added to the end of the card vector passed in
|
||
|
// the start index of the cards is also set if the function returns true
|
||
|
// the function returns true if it has cards that can be moved or false if it has none.
|
||
|
|
||
|
// this function has been added to aid in creating hints for moving cards
|
||
|
virtual bool getMovableCards(PlayingCardVector &, unsigned int & index) const;
|
||
|
|
||
|
// this function gets the point in the scene that a card would be added to this stack.
|
||
|
inline virtual QPointF getGlobalCardAddPt() const {return mapToScene(QPointF(0,0));};
|
||
|
inline virtual QPointF getGlobalLastCardPt() const {return mapToScene(QPointF(0,0));};
|
||
|
inline virtual QPointF getGlobalCardPt(int index) const {Q_UNUSED(index);return mapToScene(QPointF(0,0));};
|
||
|
|
||
|
// this function will update the bounding rectangle for the cards. And update the
|
||
|
// pixmap for the stack. The default implementation implementation just calls
|
||
|
// getStackPixmap. Subclasses may want to override this version to record bounding
|
||
|
// rectangles for cards and then call the base class.
|
||
|
virtual void updateStack();
|
||
|
|
||
|
// this function returns a pointer to a pixmap of the stack. The pixmap is the responsiblity
|
||
|
// of the caller to free. This function can be overridden in subclasses to create
|
||
|
// different look for the stack when drawn or cards from it are dragged to a different
|
||
|
// stack.
|
||
|
virtual QPixmap * getStackPixmap(const PlayingCardVector & cardVector,
|
||
|
bool highlighted=false,
|
||
|
int hintHighlightIndex=-1);
|
||
|
|
||
|
// override in subclasses for scoring per stack if desired.
|
||
|
virtual int score() const{return 0;}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
// public static functions
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
static void updateAllStacks();
|
||
|
|
||
|
static void clearAllStacks();
|
||
|
|
||
|
static inline void lockUserInteration(bool lock=true){m_lockUserInteraction=lock;}
|
||
|
static inline bool isUserInteractionLocked() {return m_lockUserInteraction;}
|
||
|
|
||
|
static CardStack * getStackByName(const std::string & stackName);
|
||
|
|
||
|
static bool isCardStack(QGraphicsItem *);
|
||
|
|
||
|
static void processCardMoveRecord(ProcessCardMoveRecordType type,
|
||
|
CardMoveRecord moveRecord);
|
||
|
|
||
|
// this is a helper function that will show a move hint by highlighting the src widget starting with the
|
||
|
// srcCardIndex in the stack for one second. And then highlighting the last card in the dest stack for
|
||
|
// one second.
|
||
|
static void showHint(CardStack * pSrcWidget,unsigned int srcCardIndex,CardStack * pDstWidget);
|
||
|
|
||
|
public slots:
|
||
|
// the slotDelayedHintHighlight() allows you to call slotHintHighlight() for the src stack
|
||
|
// and slotDelayedHintHighlight() for the destination stack at the same time.
|
||
|
void slotDelayedHintHighlight(); // show a hint highlight delayed
|
||
|
void slotHintHighlight(int index=-1); // show the highlight hint immediately it will timeout in one second
|
||
|
void slotHintHighlightComplete();
|
||
|
|
||
|
void slotFlipComplete(CardStack * pSrc);
|
||
|
|
||
|
void slotDragCardsMoved(const CardMoveRecord & moveRecord);
|
||
|
|
||
|
signals:
|
||
|
// when a card is clicked this signal is emitted
|
||
|
void cardClicked(CardStack * pCardStackWidget,unsigned int index);
|
||
|
// This signal is emitted when there are no cards
|
||
|
// in the stack and the pad area where the first card would be is clicked
|
||
|
void padClicked(CardStack * pCardStackWidget);
|
||
|
|
||
|
// this signal indicates that cards where clicked, but they are also movable
|
||
|
// and it includes a move record of what would happen if the card was moved. This
|
||
|
// can be used to make the move by calling processCardMoveRecord. If the move is accepted
|
||
|
// the add move can be added to the move record. And then processCardMoveRecord can be
|
||
|
// called to perform the move. The index is the index of the card that was clicked.
|
||
|
void movableCardsClicked(CardStack * pCardStack,
|
||
|
const PlayingCardVector & cardVector,
|
||
|
const CardMoveRecord &);
|
||
|
|
||
|
// the card record will contain all changes made by the drag and
|
||
|
// drop. The remove from one stack. The flip of the card if in
|
||
|
// autoCardUp mode and the card under the remove cards was face
|
||
|
// down. And then the add of the cards to the other stack.
|
||
|
// The signal will be emitted by the stack that started the drag
|
||
|
// operation.
|
||
|
void cardsMovedByDragDrop(const CardMoveRecord &);
|
||
|
|
||
|
protected:
|
||
|
int m_hintHighlightIndex;
|
||
|
|
||
|
// subclasses should reimplement canMoveCard and canAddCards
|
||
|
// for the rules of whatever game they are implementing.
|
||
|
virtual bool canMoveCard(unsigned int index) const{Q_UNUSED(index); return false;}
|
||
|
virtual bool getCardIndex(const QPointF & pos,unsigned int & index);
|
||
|
|
||
|
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
|
||
|
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
|
||
|
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
|
||
|
|
||
|
virtual void hoverMoveEvent ( QGraphicsSceneHoverEvent * event );
|
||
|
|
||
|
private:
|
||
|
QString m_stackName;
|
||
|
PlayingCardVector m_cardVector;
|
||
|
bool m_highlighted;
|
||
|
bool m_showRedealCircle;
|
||
|
bool m_autoFaceUp;
|
||
|
bool m_mouseMoved; // set to true if the mouse is moved while the button is down
|
||
|
// using this to determine a mouse click on the CardStack. The
|
||
|
// mouse should not move.
|
||
|
QPointF m_dragStartPos; // used to figure out when the mouse has been moved enough to
|
||
|
// start a drag operation
|
||
|
|
||
|
FlipAnimation m_flipAni;
|
||
|
DragCardStack m_dragStack;
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
// static variables
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
static CardStackMap m_cardStackMap; // this is a map that contains all of the current instances
|
||
|
// of CardStack. They are mapped by a unique name to a
|
||
|
// pointer to the instance.
|
||
|
static bool m_lockUserInteraction;
|
||
|
};
|
||
|
|
||
|
#endif
|