ksquares
gameboardscene.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "gameboardscene.h"
00011
00012 #include <math.h>
00013
00014 #include <QGraphicsSceneMouseEvent>
00015 #include <QGraphicsEllipseItem>
00016
00017 #include <kdebug.h>
00018
00019 GameBoardScene::GameBoardScene(int newWidth, int newHeight, QObject *parent) : QGraphicsScene(parent), width(newWidth), height(newHeight), acceptEvents(true)
00020 {
00021
00022
00023 for(int i = 0; i < (2*width*height + width + height); i++)
00024 {
00025 lineList.append(false);
00026 }
00027
00028 spacing = 40;
00029 for(int iWidth = 0; iWidth <= width; iWidth++)
00030 {
00031 for(int iHeight = 0; iHeight <= height; iHeight++)
00032 {
00033 int x = iWidth*spacing;
00034 int y = iHeight*spacing;
00035 QGraphicsEllipseItem *dot = new QGraphicsEllipseItem(QRectF(-2,-2,4,4));
00036 dot->moveBy(x,y);
00037 dot->setBrush(Qt::SolidPattern);
00038 dot->setZValue(20);
00039 addItem(dot);
00040 }
00041 }
00042 QPen feintPen(Qt::DotLine);
00043 feintPen.setWidth(1);
00044 feintPen.setColor(Qt::lightGray);
00045 for(int iWidth = 0; iWidth <= width; iWidth++)
00046 {
00047 addLine(QLineF(spacing*iWidth, 0, spacing*iWidth, spacing*height), feintPen);
00048 }
00049 for(int iHeight = 0; iHeight <= height; iHeight++)
00050 {
00051 addLine(QLineF(0, spacing*iHeight, spacing*width, spacing*iHeight), feintPen);
00052 }
00053
00054 setBackgroundBrush(QBrush(Qt::white));
00055
00056 indicatorLine = new QGraphicsLineItem(1,1,1,1);
00057 indicatorLine->setZValue(10);
00058 indicatorLine->setPen(QPen(Qt::yellow, 2.5));
00059 indicatorLine->hide();
00060 addItem(indicatorLine);
00061
00062 QGraphicsEllipseItem tempItem;
00063 QGraphicsEllipseItemType = tempItem.type();
00064
00065 qreal border = 10;
00066 QRectF rect = sceneRect();
00067 rect.setLeft(rect.left() - border);
00068 rect.setRight(rect.right() + border);
00069 rect.setTop(rect.top() - border);
00070 rect.setBottom(rect.bottom() + border);
00071 setSceneRect(rect);
00072 }
00073
00074 GameBoardScene::~GameBoardScene()
00075 {
00076 kDebug() << "GameBoardScene::~GameBoardScene()";
00077 delete indicatorLine;
00078 }
00079
00080 void GameBoardScene::drawLine(int index, const QColor &colour)
00081 {
00082 QGraphicsLineItem* line = lineFromIndex(index);
00083 line->setZValue(10);
00084 line->setPen(QPen(QBrush(colour), 2.5));
00085 addItem(line);
00086 lineList[index] = true;
00087 indicatorLine->hide();
00088 update(line->boundingRect());
00089 }
00090
00091 void GameBoardScene::drawSquare(int index, const QColor &colour)
00092 {
00093 QBrush brush(colour, Qt::SolidPattern);
00094
00095 addRect(QRectF(qreal((index%width)*spacing), qreal((index/width)*spacing), qreal(spacing), qreal(spacing)), QPen(), brush)->setZValue(-1);
00096 }
00097
00098 int GameBoardScene::indexFromPointPair(const QList<QGraphicsEllipseItem*> &pointPair) const
00099 {
00100
00101 if (pointPair.size() != 2)
00102 return -1;
00103
00104 qreal pointOneX = pointPair.at(0)->scenePos().x()/spacing;
00105 qreal pointOneY = pointPair.at(0)->scenePos().y()/spacing;
00106 qreal pointTwoX = pointPair.at(1)->scenePos().x()/spacing;
00107 qreal pointTwoY = pointPair.at(1)->scenePos().y()/spacing;
00108
00109
00110 qreal refX;
00111 qreal refY;
00112
00113 int index = -1;
00114 if (pointOneX == pointTwoX)
00115 {
00116
00117 refX = pointOneX;
00118 if (pointTwoY < pointOneY)
00119 refY = pointTwoY;
00120 else
00121 refY = pointOneY;
00122 index = static_cast<int>(refY * ((2*width)+1) + refX + width);
00123 }
00124
00125 else if (pointOneY == pointTwoY)
00126 {
00127
00128 refY = pointOneY;
00129 if (pointOneX < pointTwoX)
00130 refX = pointOneX;
00131 else
00132 refX = pointTwoX;
00133 index = static_cast<int>(refY * ((2*width)+1) + refX);
00134 }
00135 return index;
00136 }
00137
00138 QGraphicsLineItem* GameBoardScene::lineFromIndex(int index) const
00139 {
00140 int index2 = index % ((2*width) + 1);
00141 enum{HORIZONTAL, VERTICAL} dir;
00142 if(index2 < width)
00143 dir = HORIZONTAL;
00144 else
00145 dir = VERTICAL;
00146
00147 int yCoordStart = (index / ((2*width) + 1)) * spacing;
00148 int xCoordStart = 0;
00149 int yCoordEnd = 0;
00150 int xCoordEnd = 0;
00151 switch(dir)
00152 {
00153 case HORIZONTAL:
00154 xCoordStart = index2 * spacing;
00155 yCoordEnd = yCoordStart;
00156 xCoordEnd = xCoordStart + spacing;
00157 break;
00158 case VERTICAL:
00159 xCoordStart = (index2 - width) * spacing;
00160 yCoordEnd = yCoordStart + spacing;
00161 xCoordEnd = xCoordStart;
00162 break;
00163 }
00164 return new QGraphicsLineItem(QLineF(xCoordStart, yCoordStart, xCoordEnd, yCoordEnd));
00165 }
00166
00167 bool GameBoardScene::isLineAlready(const QList<QGraphicsEllipseItem*> &pointPair) const
00168 {
00169 int index = indexFromPointPair(pointPair);
00170 if (index == -1)
00171 return true;
00172
00173 return lineList.at(index);
00174 }
00175
00176 void GameBoardScene::addLineToIndex(const QList<QGraphicsEllipseItem*> &pointPair)
00177 {
00178 int index = indexFromPointPair(pointPair);
00179 if (index == -1)
00180 return;
00181
00182 emit lineDrawn(index);
00183 }
00184
00185 QList<QGraphicsEllipseItem*> GameBoardScene::getTwoNearestPoints(const QPointF &pos) const
00186 {
00187 QList<QGraphicsItem*> itemList = items();
00188 QList<QGraphicsEllipseItem*> connectList;
00189 for (int i = 0; i < itemList.size(); ++i)
00190 {
00191 if (itemList.at(i)->type() == QGraphicsEllipseItemType)
00192 {
00193
00194 QPointF dist(pos - itemList.at(i)->scenePos());
00195 qreal distMod = sqrt(dist.x()*dist.x() + dist.y()*dist.y());
00196
00197 if (distMod < spacing-5)
00198 {
00199 connectList << qgraphicsitem_cast<QGraphicsEllipseItem*>(itemList.at(i));
00200 }
00201 }
00202 }
00203 return connectList;
00204 }
00205
00206 const QSize GameBoardScene::minimumSizeHint() const
00207 {
00208 return QSize((width*spacing)+10, (height*spacing)+10);
00209 }
00210
00211
00212
00213
00214
00215
00216
00217 void GameBoardScene::mouseReleaseEvent (QGraphicsSceneMouseEvent* mouseEvent)
00218 {
00219 if (!acceptEvents)
00220 {
00221 QGraphicsScene::mouseReleaseEvent(mouseEvent);
00222 return;
00223 }
00224
00225
00226 if (mouseEvent->button() == Qt::LeftButton)
00227 {
00228 QList<QGraphicsEllipseItem*> connectList = getTwoNearestPoints(mouseEvent->scenePos());
00229 if (connectList.size() == 2)
00230 {
00231 addLineToIndex(connectList);
00232 }
00233 }
00234
00235 QGraphicsScene::mouseReleaseEvent(mouseEvent);
00236 }
00237
00238 void GameBoardScene::mouseMoveEvent (QGraphicsSceneMouseEvent* mouseEvent)
00239 {
00240 if (!acceptEvents) return;
00241
00242
00243
00244
00245
00246 QList<QGraphicsEllipseItem*> connectList = getTwoNearestPoints(mouseEvent->scenePos());
00247
00248 if (connectList.size() == 2 && !isLineAlready(connectList))
00249 {
00250 indicatorLine->setLine(QLineF(connectList.at(0)->scenePos(), connectList.at(1)->scenePos()));
00251 indicatorLine->show();
00252 }
00253 else
00254 {
00255 indicatorLine->hide();
00256 }
00257
00258 QGraphicsScene::mouseMoveEvent(mouseEvent);
00259 }
00260
00261 #include "gameboardscene.moc"