• Skip to content
  • Skip to link menu
KDE 4.0 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

ksquares

gameboardscene.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2006 by Matthew Williams    <matt@milliams.com>         *
00003  *                                                                         *
00004  *   This program is free software; you can redistribute it and/or modify  *
00005  *   it under the terms of the GNU General Public License as published by  *
00006  *   the Free Software Foundation; either version 2 of the License, or     *
00007  *   (at your option) any later version.                                   *
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     //kDebug() << "GameBoardScene::GameBoardScene()";
00022     
00023     for(int i = 0; i < (2*width*height + width + height); i++)
00024     {
00025         lineList.append(false); //simply fill array with 'false's
00026     }
00027     
00028     spacing = 40;   //this hard coding doesn't matter since auto-resizing exists :)
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); // set the elevation, the dot's are on top
00039             addItem(dot);
00040         }
00041     }
00042     QPen feintPen(Qt::DotLine); //for the guidelines between dots
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);  //draw new line
00086     lineList[index] = true; //keep this table in sync
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; // if it isn't a pair
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     //this int conversion could go bad but SHOULD be safe
00110     qreal refX; // these two will be the grid-coord of the
00111     qreal refY; // to and left most point of the two
00112     
00113     int index = -1;
00114     if (pointOneX == pointTwoX)
00115     {
00116         //dir = VERTICAL;
00117         refX = pointOneX;
00118         if (pointTwoY < pointOneY)  //want the topmost point as reference
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         //dir = HORIZONTAL;
00128         refY = pointOneY;
00129         if (pointOneX < pointTwoX)  //want the leftmost point as reference
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 //TODO does this work?
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)    //not a valid line since no two unique ends
00180         return;
00181     
00182     emit lineDrawn(index);  //addLineToIndex(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             //cout << "itemList.at(i)->scenePos():" << qgraphicsitem_cast<QGraphicsEllipseItem*>(itemList.at(i))->scenePos().x() << "," << qgraphicsitem_cast<QGraphicsEllipseItem*>(itemList.at(i))->scenePos().y() << endl;
00194             QPointF dist(pos - itemList.at(i)->scenePos());
00195             qreal distMod = sqrt(dist.x()*dist.x() + dist.y()*dist.y());
00196             //if (distMod < (spacing*0.7071))   //there will only ever be either 1 or 2 items that fulfil this [0.7071 ~ 2^(-0.5)]
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);  // the +10 is to provide padding and to avoid scrollbars
00209 }
00210 
00211 /*void GameBoardScene::mousePressEvent (QGraphicsSceneMouseEvent* mouseEvent)
00212 {
00213     if (!acceptEvents) return;
00214     QGraphicsScene::mousePressEvent(mouseEvent);
00215 }*/
00216 
00217 void GameBoardScene::mouseReleaseEvent (QGraphicsSceneMouseEvent* mouseEvent)
00218 {
00219     if (!acceptEvents) 
00220     {
00221         QGraphicsScene::mouseReleaseEvent(mouseEvent);
00222         return;
00223     }
00224 
00225     //cout << "GameBoardScene::mouseReleaseEvent" << endl;
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     //indicatorLine = 0;
00242     
00243     //kDebug() << "GameBoardScene::mouseMoveEvent";
00244     //kDebug() << "mouseEvent->scenePos():" << mouseEvent->scenePos().x() << "," << mouseEvent->scenePos().y();
00245     
00246     QList<QGraphicsEllipseItem*> connectList = getTwoNearestPoints(mouseEvent->scenePos());
00247     
00248     if (connectList.size() == 2 && !isLineAlready(connectList))
00249     {   //if there are two nearest points and there isn't already a line
00250         indicatorLine->setLine(QLineF(connectList.at(0)->scenePos(), connectList.at(1)->scenePos()));   //where
00251         indicatorLine->show();
00252     }
00253     else
00254     {
00255         indicatorLine->hide();
00256     }
00257     
00258     QGraphicsScene::mouseMoveEvent(mouseEvent);
00259 }
00260 
00261 #include "gameboardscene.moc"

ksquares

Skip menu "ksquares"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • kblackbox
  • kgoldrunner
  • kmahjongg
  • ksquares
  • libkdegames
  •   highscore
  •   kgame
  •   kggzgames
  •   kggzmod
  •   kggznet
  • libkmahjongg
Generated for API Reference by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal