diff options
author | Jason Katz-Brown <jason@airbnb.com> | 2013-08-25 02:17:13 -0700 |
---|---|---|
committer | Jason Katz-Brown <jason@airbnb.com> | 2013-08-25 02:17:13 -0700 |
commit | 9306cb60c32082c5403931de0823a9fd5daa196c (patch) | |
tree | ca1b6eb695fdf3f0c2294e92416b272164bae642 /quacker/rackdisplay.cpp | |
parent | 8fb2c681cecc01b46b0f4ba02d5cc177c4747b1c (diff) |
Initial git commit.
Diffstat (limited to 'quacker/rackdisplay.cpp')
-rw-r--r-- | quacker/rackdisplay.cpp | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/quacker/rackdisplay.cpp b/quacker/rackdisplay.cpp new file mode 100644 index 0000000..d178285 --- /dev/null +++ b/quacker/rackdisplay.cpp @@ -0,0 +1,279 @@ +/* + * Quackle -- Crossword game artificial intelligence and analysis tool + * Copyright (C) 2005-2006 Jason Katz-Brown and John O'Laughlin. + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <iostream> + +#include <QtGui> + +#include <game.h> +#include <quackleio/util.h> + +#include "geometry.h" +#include "graphicalboard.h" +#include "rackdisplay.h" + +QuickEntryRack::QuickEntryRack(QWidget *parent) + : View(parent) +{ + QHBoxLayout *textLayout = new QHBoxLayout(); + Geometry::setupInnerLayout(textLayout); + + m_lineEdit = new QLineEdit; + m_lineEdit->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + connect(m_lineEdit, SIGNAL(returnPressed()), this, SLOT(quickEditReturnPressed())); + + QPushButton *setButton = new QPushButton(tr("Set Rack")); + connect(setButton, SIGNAL(clicked()), this, SLOT(quickEditReturnPressed())); + + QPushButton *shuffleButton = new QPushButton(tr("Shu&ffle")); + connect(shuffleButton, SIGNAL(clicked()), this, SLOT(shuffle())); + + m_label = new QLabel(tr("&Rack")); + m_label->setBuddy(m_lineEdit); + textLayout->addWidget(m_label, 1); + textLayout->addWidget(m_lineEdit, 4); + textLayout->addWidget(setButton, 1); + textLayout->addWidget(shuffleButton, 1); + + m_tiles = new GraphicalRack; + + QVBoxLayout *layout = new QVBoxLayout; + Geometry::setupInnerLayout(layout); + layout->addWidget(m_tiles); + layout->addLayout(textLayout); + setLayout(layout); +} + +QuickEntryRack::~QuickEntryRack() +{ +} + +void QuickEntryRack::positionChanged(const Quackle::GamePosition &position) +{ + if (m_rackTiles == position.currentPlayer().rack().tiles()) + return; + + m_rackTiles = position.currentPlayer().rack().tiles(); + QString tiles = QuackleIO::Util::letterStringToQString(m_rackTiles); + m_lineEdit->setText(tiles); + m_label->setText(QString("%1's &rack:").arg(QuackleIO::Util::uvStringToQString(position.currentPlayer().name()))); + m_tiles->setText(m_rackTiles); +} + +void QuickEntryRack::grabFocus() +{ + m_lineEdit->setFocus(); + m_lineEdit->selectAll(); +} + +void QuickEntryRack::quickEditReturnPressed() +{ + QString text(m_lineEdit->text()); + m_lineEdit->clear(); + processRack(text); +} + +void QuickEntryRack::processRack(const QString &rack) +{ + if (rack.isEmpty()) + { + emit statusMessage(tr("Useless rack.")); + return; + } + + emit setRack(QuackleIO::Util::makeRack(rack)); +} + +void QuickEntryRack::shuffle() +{ + Quackle::Rack rack(QuackleIO::Util::makeRack(m_lineEdit->text())); + rack.shuffle(); + + emit setRack(rack); +} + +GraphicalRack::GraphicalRack(QWidget * parent) + : QFrame(parent) +{ + m_layout = new QHBoxLayout(this); + Geometry::setupInnerLayout(m_layout); + m_layout->addStretch(); + + setAcceptDrops(true); + setMinimumSize(50, 50); +} + +void +GraphicalRack::setText(const Quackle::LetterString &text) +{ + // clear old labels + while(m_layout->count()) { + QLabel *label = qobject_cast<QLabel*>(m_layout->itemAt(0)->widget()); + if (!label) { + break; + } + m_layout->removeWidget(label); + label->close(); + } + + PixmapCacher::self()->invalidate(); + for (int i = text.size() - 1; i >= 0 ; --i) { + QLabel *label = new QLabel; + label->setAttribute (Qt::WA_DeleteOnClose); + + TileWidget tile; + Quackle::Board::TileInformation info; + info.isOnRack = true; + info.letter = text[i]; + info.tileType = Quackle::Board::LetterTile; + tile.setInformation(info); + tile.setSideLength(50); + tile.prepare(); + + label->setPixmap(tile.tilePixmap()); + + m_layout->insertWidget(0, label); + } +} + +const QString GraphicalRack::mime_type = "application/x-quackle-tile"; + +void +GraphicalRack::dragEnterEvent (QDragEnterEvent* event) +{ + if (event->mimeData()->hasFormat(mime_type)) + { + if (event->source() == this) { + event->setDropAction (Qt::MoveAction); + event->accept(); + } else { + event->acceptProposedAction(); + } + } else { + event->ignore(); + } +} + +//--------------------------------------------------------------------------- +// dropEvent +// +//! The event handler that receives drop events. +// +//! @param event the drop event +//--------------------------------------------------------------------------- +void +GraphicalRack::dropEvent (QDropEvent* event) +{ + if (event->mimeData()->hasFormat (mime_type)) { + QByteArray itemData = event->mimeData()->data (mime_type); + QDataStream dataStream(&itemData, QIODevice::ReadOnly); + + QPixmap pixmap; + QPoint sourcePos; + QPoint offset; + dataStream >> pixmap >> sourcePos >> offset; + + QLabel* droppedTile = new QLabel; + droppedTile->setPixmap(pixmap); + droppedTile->setAttribute (Qt::WA_DeleteOnClose); + + QPoint dropPos = event->pos() - offset; + + // Move the tile an extra half tile width in the direction of the + // move. This allows the tile to assume a new spot if it is dragged + // more than halfway onto the spot. + int extraMove = (sourcePos.x() < dropPos.x() ? 50 / 2 + : -50 / 2); + + dropPos.setX(dropPos.x() + extraMove); + + for(int i = 0; i < m_layout->count(); ++i) { + QLabel *label = qobject_cast<QLabel*>(m_layout->itemAt(i)->widget()); + if (!label) { // hit the stretcher + m_layout->insertWidget(i, droppedTile); + break; + } + if (dropPos.x() > label->pos().x()) { + continue; + } + m_layout->insertWidget(i, droppedTile); + break; + } + + if (event->source() == this) { + event->setDropAction (Qt::MoveAction); + event->accept(); + } else { + event->acceptProposedAction(); + } + } + else { + event->ignore(); + } +} + +//--------------------------------------------------------------------------- +// mousePressEvent +// +//! The event handler that receives mouse press events. +// +//! @param event the mouse press event +//--------------------------------------------------------------------------- +void +GraphicalRack::mousePressEvent (QMouseEvent* event) +{ + QLabel* child = qobject_cast<QLabel*>(childAt (event->pos())); + if (!child) + return; + + QPixmap pixmap = *(child->pixmap()); + + QByteArray itemData; + QDataStream dataStream (&itemData, QIODevice::WriteOnly); + dataStream << pixmap << QPoint (event->pos()) + << QPoint (event->pos() - child->pos()); + + QMimeData *mimeData = new QMimeData; + mimeData->setData (mime_type, itemData); + + QDrag *drag = new QDrag (this); + drag->setMimeData (mimeData); + drag->setPixmap (pixmap); + drag->setHotSpot (event->pos() - child->pos()); + + QColor bgColor = palette().color(QPalette::Window); + + QPixmap tempPixmap = pixmap; + QPainter painter; + painter.begin (&tempPixmap); + painter.fillRect(pixmap.rect(), QColor(bgColor.red(), bgColor.green(), + bgColor.blue(), 127)); + painter.end(); + + child->setPixmap (tempPixmap); + + if (drag->start (Qt::CopyAction | Qt::MoveAction) == Qt::MoveAction) { + child->close(); + } + else { + child->show(); + child->setPixmap (pixmap); + } +} |