From 0f272a2f5170bd1256880e4085bfdceea8002f90 Mon Sep 17 00:00:00 2001 From: brukie Date: Tue, 16 Jun 2009 18:20:29 +0200 Subject: [PATCH] improved card dragging --- cockatrice/src/carddatabase.cpp | 11 ++-- cockatrice/src/carddragitem.cpp | 92 ++++++++++++++++++------------- cockatrice/src/carddragitem.h | 9 +-- cockatrice/src/cardinfowidget.cpp | 22 +++++--- cockatrice/src/carditem.cpp | 40 +++++++++++--- cockatrice/src/carditem.h | 9 +-- cockatrice/src/gravezone.cpp | 2 +- cockatrice/src/libraryzone.cpp | 2 +- cockatrice/src/rfgzone.cpp | 2 +- 9 files changed, 115 insertions(+), 74 deletions(-) diff --git a/cockatrice/src/carddatabase.cpp b/cockatrice/src/carddatabase.cpp index ded280dd5..6a7988d12 100644 --- a/cockatrice/src/carddatabase.cpp +++ b/cockatrice/src/carddatabase.cpp @@ -88,19 +88,22 @@ QPixmap *CardInfo::loadPixmap() if (pixmap->load(QString("../pics/%1/%2%3.full.jpg").arg(editions.at(i)).arg(correctedName).arg(1))) return pixmap; } - pixmap->load("../pics/none.jpg"); return pixmap; } QPixmap *CardInfo::getPixmap(QSize size) { qDebug(QString("CardInfo::getPixmap(%1, %2) for %3").arg(size.width()).arg(size.height()).arg(getName()).toLatin1()); - if (QPixmap *result = scaledPixmapCache.value(size.width())) { + QPixmap *cachedPixmap = scaledPixmapCache.value(size.width()); + if (cachedPixmap) { qDebug("cache HIT"); - return result; + return cachedPixmap; } qDebug("cache MISS"); - QPixmap *result = new QPixmap(loadPixmap()->scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + QPixmap *bigPixmap = loadPixmap(); + if (bigPixmap->isNull()) + return 0; + QPixmap *result = new QPixmap(bigPixmap->scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); scaledPixmapCache.insert(size.width(), result); return result; } diff --git a/cockatrice/src/carddragitem.cpp b/cockatrice/src/carddragitem.cpp index cde021aea..51d343b2a 100644 --- a/cockatrice/src/carddragitem.cpp +++ b/cockatrice/src/carddragitem.cpp @@ -3,90 +3,104 @@ #include "carddatabase.h" #include -CardDragItem::CardDragItem(QGraphicsScene *scene, CardZone *_startZone, CardInfo *_info, int _id, const QPointF &_hotSpot, bool _faceDown, QGraphicsItem *parent) - : QGraphicsItem(parent), id(_id), info(_info), hotSpot(_hotSpot), startZone(_startZone), faceDown(_faceDown) +CardDragItem::CardDragItem(CardItem *_item, int _id, const QPointF &_hotSpot, bool _faceDown, CardDragItem *parentDrag) + : QGraphicsItem(), id(_id), item(_item), hotSpot(_hotSpot), faceDown(_faceDown) { - if ((hotSpot.x() < 0) || (hotSpot.y() < 0)) { - qDebug(QString("CardDragItem: coordinate overflow: x = %1, y = %2").arg(hotSpot.x()).arg(hotSpot.y()).toLatin1()); - hotSpot = QPointF(); - } else if ((hotSpot.x() > CARD_WIDTH) || (hotSpot.y() > CARD_HEIGHT)) { - qDebug(QString("CardDragItem: coordinate overflow: x = %1, y = %2").arg(hotSpot.x()).arg(hotSpot.y()).toLatin1()); - hotSpot = QPointF(CARD_WIDTH, CARD_HEIGHT); + if (parentDrag) + parentDrag->addChildDrag(this); + else { + if ((hotSpot.x() < 0) || (hotSpot.y() < 0)) { + qDebug(QString("CardDragItem: coordinate overflow: x = %1, y = %2").arg(hotSpot.x()).arg(hotSpot.y()).toLatin1()); + hotSpot = QPointF(); + } else if ((hotSpot.x() > CARD_WIDTH) || (hotSpot.y() > CARD_HEIGHT)) { + qDebug(QString("CardDragItem: coordinate overflow: x = %1, y = %2").arg(hotSpot.x()).arg(hotSpot.y()).toLatin1()); + hotSpot = QPointF(CARD_WIDTH, CARD_HEIGHT); + } + setCursor(Qt::ClosedHandCursor); } + if (item->getTapped()) + setTransform(QTransform().translate((float) CARD_WIDTH / 2, (float) CARD_HEIGHT / 2).rotate(90).translate((float) -CARD_WIDTH / 2, (float) -CARD_HEIGHT / 2)); setZValue(2000000000); setCacheMode(DeviceCoordinateCache); - setCursor(Qt::ClosedHandCursor); - - if (!parent) - scene->addItem(this); } CardDragItem::~CardDragItem() { qDebug("CardDragItem destructor"); + for (int i = 0; i < childDrags.size(); i++) + delete childDrags[i]; } -QRectF CardDragItem::boundingRect() const +void CardDragItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { - return QRectF(0, 0, CARD_WIDTH, CARD_HEIGHT); -} - -void CardDragItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget */*widget*/) -{ - QSizeF translatedSize = option->matrix.mapRect(boundingRect()).size(); - QPixmap *translatedPixmap = info->getPixmap(translatedSize.toSize()); - painter->drawPixmap(boundingRect(), *translatedPixmap, translatedPixmap->rect()); + item->paint(painter, option, widget); } void CardDragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { + event->accept(); QPointF sp = event->scenePos(); QList colliding = scene()->items(sp); CardZone *cursorZone = 0; - for (int i = colliding.size() - 1; i >= 0; i--) { - if ((cursorZone = qgraphicsitem_cast(colliding.at(i)))) { - if (cursorZone->getName() == "table") { - QPointF cp = cursorZone->scenePos(); - QPointF localpos = sp - hotSpot - cp; - setPos(QPointF(round(localpos.x() / RASTER_WIDTH) * RASTER_WIDTH, round(localpos.y() / RASTER_HEIGHT) * RASTER_HEIGHT) + cp); - } else - setPos(sp - hotSpot); + for (int i = colliding.size() - 1; i >= 0; i--) + if ((cursorZone = qgraphicsitem_cast(colliding.at(i)))) break; - } + + QPointF newPos; + if (!cursorZone) + return; + else if (cursorZone->getName() == "table") { + QPointF cp = cursorZone->scenePos(); + QPointF localpos = sp - hotSpot - cp; + + newPos = QPointF(round(localpos.x() / RASTER_WIDTH) * RASTER_WIDTH, round(localpos.y() / RASTER_HEIGHT) * RASTER_HEIGHT) + cp; + } else + newPos = sp - hotSpot; + if (newPos != pos()) { + for (int i = 0; i < childDrags.size(); i++) + childDrags[i]->setPos(newPos + childDrags[i]->getHotSpot()); +// qDebug(QString("setPos: x=%1, y=%2").arg(newPos.x()).arg(newPos.y()).toLatin1()); + setPos(newPos); } - event->accept(); } void CardDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { setCursor(Qt::OpenHandCursor); QGraphicsScene *sc = scene(); - QPointF sp = scenePos(); + QPointF sp = pos(); + qDebug(QString("sp: x=%1, y=%2").arg(sp.x()).arg(sp.y()).toLatin1()); sc->removeItem(this); QList colliding = sc->items(event->scenePos()); - qDebug(QString("drop: %1 collisions").arg(colliding.size()).toLatin1()); +// qDebug(QString("drop: %1 collisions").arg(colliding.size()).toLatin1()); CardZone *dropZone = 0; for (int i = colliding.size() - 1; i >= 0; i--) { QRectF bbox = colliding.at(i)->boundingRect(); - qDebug(QString("bbox x %1 y %2 w %3 h %4").arg(bbox.x()).arg(bbox.y()).arg(bbox.width()).arg(bbox.height()).toLatin1()); +// qDebug(QString("bbox x %1 y %2 w %3 h %4").arg(bbox.x()).arg(bbox.y()).arg(bbox.width()).arg(bbox.height()).toLatin1()); if ((dropZone = qgraphicsitem_cast(colliding.at(i)))) { - qDebug("zone found"); +// qDebug("zone found"); break; } } if (dropZone) { + CardZone *startZone = qgraphicsitem_cast(item->parentItem()); dropZone->handleDropEvent(id, startZone, (sp - dropZone->scenePos()).toPoint(), faceDown); - QList childList = childItems(); - for (int i = 0; i < childList.size(); i++) { - CardDragItem *c = qgraphicsitem_cast(childList.at(i)); - dropZone->handleDropEvent(c->id, startZone, (sp - dropZone->scenePos() + c->pos()).toPoint(), faceDown); + for (int i = 0; i < childDrags.size(); i++) { + CardDragItem *c = childDrags[i]; + dropZone->handleDropEvent(c->id, startZone, (sp - dropZone->scenePos() + c->getHotSpot()).toPoint(), faceDown); + sc->removeItem(c); } } event->accept(); } + +void CardDragItem::addChildDrag(CardDragItem *child) +{ + childDrags << child; +} diff --git a/cockatrice/src/carddragitem.h b/cockatrice/src/carddragitem.h index 1eb3df795..82196238b 100644 --- a/cockatrice/src/carddragitem.h +++ b/cockatrice/src/carddragitem.h @@ -10,18 +10,19 @@ class CardInfo; class CardDragItem : public QGraphicsItem { private: int id; - CardInfo *info; + CardItem *item; QPointF hotSpot; - CardZone *startZone; bool faceDown; + QList childDrags; public: enum { Type = typeCardDrag }; int type() const { return Type; } - CardDragItem(QGraphicsScene *scene, CardZone *_startZone, CardInfo *_info, int _id, const QPointF &_hotSpot, bool _faceDown, QGraphicsItem *parent = 0); + CardDragItem(CardItem *_item, int _id, const QPointF &_hotSpot, bool _faceDown, CardDragItem *parentDrag = 0); ~CardDragItem(); - QRectF boundingRect() const; + QRectF boundingRect() const { return QRectF(0, 0, CARD_WIDTH, CARD_HEIGHT); } void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); QPointF getHotSpot() const { return hotSpot; } + void addChildDrag(CardDragItem *child); protected: void mouseMoveEvent(QGraphicsSceneMouseEvent *event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); diff --git a/cockatrice/src/cardinfowidget.cpp b/cockatrice/src/cardinfowidget.cpp index 3fc0c16c5..29474b2a3 100644 --- a/cockatrice/src/cardinfowidget.cpp +++ b/cockatrice/src/cardinfowidget.cpp @@ -2,9 +2,10 @@ #include #include #include +#include CardInfoWidget::CardInfoWidget(CardDatabase *_db, QWidget *parent) - : QFrame(parent), db(_db), pixmapHeight(0) + : QFrame(parent), db(_db), pixmapHeight(pixmapWidth) { cardPicture = new QLabel(); cardPicture->setAlignment(Qt::AlignCenter); @@ -50,8 +51,15 @@ CardInfoWidget::CardInfoWidget(CardDatabase *_db, QWidget *parent) grid->setRowStretch(5, 1); grid->setColumnStretch(1, 1); + CardInfo *cardBack = db->getCard(); + QPixmap *bigPixmap = cardBack->loadPixmap(); + if (bigPixmap->isNull()) + QMessageBox::critical(this, tr("Error"), tr("Unable to load pixmap for card back.")); + else + pixmapHeight = pixmapWidth * bigPixmap->height() / bigPixmap->width(); + setCard(cardBack); + setFrameStyle(QFrame::Panel | QFrame::Raised); - setCard(db->getCard()); setFixedSize(sizeHint()); } @@ -60,11 +68,11 @@ void CardInfoWidget::setCard(CardInfo *card) if (!card) return; - if (pixmapHeight == 0) { - QPixmap *bigPixmap = card->loadPixmap(); - pixmapHeight = pixmapWidth * bigPixmap->height() / bigPixmap->width(); - } - cardPicture->setPixmap(*card->getPixmap(QSize(pixmapWidth, pixmapHeight))); + QPixmap *resizedPixmap = card->getPixmap(QSize(pixmapWidth, pixmapHeight)); + if (resizedPixmap) + cardPicture->setPixmap(*resizedPixmap); + else + cardPicture->setPixmap(*(db->getCard()->getPixmap(QSize(pixmapWidth, pixmapHeight)))); nameLabel2->setText(card->getName()); manacostLabel2->setText(card->getManacost()); diff --git a/cockatrice/src/carditem.cpp b/cockatrice/src/carditem.cpp index 51f3d3078..3876df248 100644 --- a/cockatrice/src/carditem.cpp +++ b/cockatrice/src/carditem.cpp @@ -35,15 +35,35 @@ void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, if (tapped) translatedSize.transpose(); QPixmap *translatedPixmap = db->getCard(name)->getPixmap(translatedSize.toSize()); - painter->drawPixmap(boundingRect(), *translatedPixmap, translatedPixmap->rect()); + painter->save(); + if (translatedPixmap) { + painter->resetTransform(); + if (tapped) { + painter->translate(((qreal) translatedSize.height()) / 2, ((qreal) translatedSize.width()) / 2); + painter->rotate(90); + painter->translate(-((qreal) translatedSize.width()) / 2, -((qreal) translatedSize.height()) / 2); + } + painter->drawPixmap(translatedPixmap->rect(), *translatedPixmap, translatedPixmap->rect()); + } else { + QFont f; + f.setStyleHint(QFont::Serif); + f.setPointSize(8); + f.setWeight(QFont::Bold); + painter->setFont(f); + painter->setBrush(QColor(200, 200, 200)); + painter->setPen(QPen(Qt::black)); + painter->drawRect(0.5, 0.5, CARD_WIDTH - 1, CARD_HEIGHT - 1); + painter->drawText(QRectF(5, 5, CARD_WIDTH - 15, CARD_HEIGHT - 15), Qt::AlignTop | Qt::AlignLeft | Qt::TextWordWrap, name); + } + painter->restore(); if (isSelected()) { - painter->setPen(QPen(QColor("red"))); - painter->drawRect(QRectF(1, 1, CARD_WIDTH - 2, CARD_HEIGHT - 2)); + painter->setPen(Qt::red); + painter->drawRect(QRectF(0.5, 0.5, CARD_WIDTH - 1, CARD_HEIGHT - 1)); } if (counters) { painter->setFont(QFont("Times", 32, QFont::Bold)); - painter->setPen(QPen(QColor("black"))); + painter->setPen(QPen(Qt::black)); painter->setBackground(QBrush(QColor(255, 255, 255, 100))); painter->setBackgroundMode(Qt::OpaqueMode); painter->drawText(boundingRect(), Qt::AlignCenter, QString::number(counters)); @@ -107,10 +127,11 @@ void CardItem::resetState() update(boundingRect()); } -CardDragItem *CardItem::createDragItem(CardZone *startZone, int _id, const QPointF &_pos, const QPointF &_scenePos, bool faceDown) +CardDragItem *CardItem::createDragItem(int _id, const QPointF &_pos, const QPointF &_scenePos, bool faceDown) { deleteDragItem(); - dragItem = new CardDragItem(scene(), startZone, db->getCard(name), _id, _pos, faceDown); + dragItem = new CardDragItem(this, _id, _pos, faceDown); + scene()->addItem(dragItem); dragItem->setPos(_scenePos - dragItem->getHotSpot()); return dragItem; @@ -142,7 +163,7 @@ void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) return; bool faceDown = event->modifiers().testFlag(Qt::ShiftModifier) || facedown; - createDragItem((CardZone *) parentItem(), id, event->pos(), event->scenePos(), faceDown); + createDragItem(id, event->pos(), event->scenePos(), faceDown); dragItem->grabMouse(); QList sel = scene()->selectedItems(); @@ -150,8 +171,9 @@ void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) CardItem *c = (CardItem *) sel.at(i); if (c == this) continue; - CardDragItem *drag = new CardDragItem(scene(), (CardZone *) parentItem(), db->getCard(c->getName()), c->getId(), QPointF(), false, dragItem); - drag->setPos(c->pos() - pos()); + CardDragItem *drag = new CardDragItem(c, c->getId(), c->pos() - pos(), false, dragItem); + drag->setPos(dragItem->pos() + c->pos() - pos()); + scene()->addItem(drag); } setCursor(Qt::OpenHandCursor); } diff --git a/cockatrice/src/carditem.h b/cockatrice/src/carditem.h index 94ac3fc53..669ccae2f 100644 --- a/cockatrice/src/carditem.h +++ b/cockatrice/src/carditem.h @@ -13,13 +13,6 @@ const int CARD_HEIGHT = 102; const int RASTER_WIDTH = 36; const int RASTER_HEIGHT = 34; -/* -const int CARD_WIDTH = 72; -const int CARD_HEIGHT = 108; -const int RASTER_WIDTH = 36; -const int RASTER_HEIGHT = 36; -*/ - const int MAX_COUNTERS_ON_CARD = 999; enum CardItemType { @@ -66,7 +59,7 @@ public: void setDoesntUntap(bool _doesntUntap); void resetState(); - CardDragItem *createDragItem(CardZone *startZone, int _id, const QPointF &_pos, const QPointF &_scenePos, bool faceDown); + CardDragItem *createDragItem(int _id, const QPointF &_pos, const QPointF &_scenePos, bool faceDown); void deleteDragItem(); protected: void mousePressEvent(QGraphicsSceneMouseEvent *event); diff --git a/cockatrice/src/gravezone.cpp b/cockatrice/src/gravezone.cpp index b1d79dae4..522848cf3 100644 --- a/cockatrice/src/gravezone.cpp +++ b/cockatrice/src/gravezone.cpp @@ -75,7 +75,7 @@ void GraveZone::mouseMoveEvent(QGraphicsSceneMouseEvent *event) bool faceDown = event->modifiers().testFlag(Qt::ShiftModifier); CardItem *card = cards->at(0); - CardDragItem *drag = card->createDragItem(this, card->getId(), event->pos(), event->scenePos(), faceDown); + CardDragItem *drag = card->createDragItem(card->getId(), event->pos(), event->scenePos(), faceDown); drag->grabMouse(); setCursor(Qt::OpenHandCursor); } diff --git a/cockatrice/src/libraryzone.cpp b/cockatrice/src/libraryzone.cpp index 2a2f74eb4..cb853923e 100644 --- a/cockatrice/src/libraryzone.cpp +++ b/cockatrice/src/libraryzone.cpp @@ -76,7 +76,7 @@ void LibraryZone::mouseMoveEvent(QGraphicsSceneMouseEvent *event) bool faceDown = event->modifiers().testFlag(Qt::ShiftModifier); CardItem *card = cards->at(0); - CardDragItem *drag = card->createDragItem(this, 0, event->pos(), event->scenePos(), faceDown); + CardDragItem *drag = card->createDragItem(0, event->pos(), event->scenePos(), faceDown); drag->grabMouse(); setCursor(Qt::OpenHandCursor); } diff --git a/cockatrice/src/rfgzone.cpp b/cockatrice/src/rfgzone.cpp index bd21224a2..3d0788f59 100644 --- a/cockatrice/src/rfgzone.cpp +++ b/cockatrice/src/rfgzone.cpp @@ -73,7 +73,7 @@ void RfgZone::mouseMoveEvent(QGraphicsSceneMouseEvent *event) bool faceDown = event->modifiers().testFlag(Qt::ShiftModifier); CardItem *card = cards->at(0); - CardDragItem *drag = card->createDragItem(this, card->getId(), event->pos(), event->scenePos(), faceDown); + CardDragItem *drag = card->createDragItem(card->getId(), event->pos(), event->scenePos(), faceDown); drag->grabMouse(); setCursor(Qt::OpenHandCursor); }