#ifndef TABLEZONE_H #define TABLEZONE_H #include "abstractcarditem.h" #include "selectzone.h" /* * TableZone is the grid based rect where CardItems may be placed. * It is the main play zone and can be customized with background images. * * TODO: Refactor methods to make more readable, extract some logic to * private methods (Im looking at you TableZone::reorganizeCards()) */ class TableZone : public SelectZone { Q_OBJECT signals: void sizeChanged(); private: static const int TABLEROWS = 3; /* Margins between table edges and cards, paddings between cards */ static const int MARGIN_LEFT = 20; static const int MARGIN_RIGHT = 15; static const int MARGIN_TOP = 10; static const int MARGIN_BOTTOM = 30; static const int PADDING_X = 35; static const int PADDING_Y = 30; /* Minimum width of the table zone including margins. */ static const int MIN_WIDTH = MARGIN_LEFT + (5 * CARD_WIDTH) + MARGIN_RIGHT; /* Offset sizes when cards are stacked on each other in the grid */ static const int STACKED_CARD_OFFSET_X = CARD_WIDTH / 3; static const int STACKED_CARD_OFFSET_Y = PADDING_Y / 3; /* Width of the box line drawn in the margin around the active player's area */ static const int BOX_LINE_WIDTH = 10; /* Default inactive mask and border gradient */ static const QColor BACKGROUND_COLOR; static const QColor FADE_MASK; static const QColor GRADIENT_COLOR; static const QColor GRADIENT_COLORLESS; /* Size and shape variables */ int width; int height; int currentMinimumWidth; /* Internal cache for widths of stacks of cards by row and column. */ QMap cardStackWidth; /* Holds any custom background image for the TableZone */ QPixmap backgroundPixelMap; /* If this TableZone is currently active */ bool active; bool isInverted() const; private slots: /** Loads in any found custom background and updates */ void updateBg(); public slots: /** Reorganizes CardItems in the TableZone */ void reorganizeCards(); public: /** Constructs TableZone. @param _p the Player @param parent defaults to null */ TableZone(Player *_p, QGraphicsItem *parent = nullptr); /** @return a QRectF of the TableZone bounding box. */ QRectF boundingRect() const; /** Render the TableZone @param painter @param option */ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); /** Toggles the selected items as tapped. */ void toggleTapped(); /** See HandleDropEventByGrid */ void handleDropEvent(const QList &dragItems, CardZone *startZone, const QPoint &dropPoint); /** Handles the placement of cards */ void handleDropEventByGrid(const QList &dragItems, CardZone *startZone, const QPoint &gridPoint); /** @return CardItem from grid location */ CardItem *getCardFromGrid(const QPoint &gridPoint) const; /** @return CardItem from coordinate location */ CardItem *getCardFromCoords(const QPointF &point) const; QPointF closestGridPoint(const QPointF &point); static int clampValidTableRow(const int row); /** Removes a card from view. @param position card position @param cardId id of card to take @param canResize defaults to true @return CardItem that has been removed */ CardItem *takeCard(int position, int cardId, bool canResize = true); /** Resizes the TableZone in case CardItems are within or outside of the TableZone constraints. */ void resizeToContents(); int getMinimumWidth() const { return currentMinimumWidth; } void setWidth(qreal _width) { prepareGeometryChange(); width = _width; } qreal getWidth() const { return width; } void setActive(bool _active) { active = _active; update(); } protected: void addCardImpl(CardItem *card, int x, int y); private: void paintZoneOutline(QPainter *painter); void paintLandDivider(QPainter *painter); /* Calculates card stack widths so mapping functions work properly */ void computeCardStackWidths(); /* Mapping functions for points to/from gridpoints. */ QPointF mapFromGrid(QPoint gridPoint) const; QPoint mapToGrid(const QPointF &mapPoint) const; /* Helper function to create a single key from a card stack location. */ int getCardStackMapKey(int x, int y) const { return x + (y * 1000); } }; #endif