📄 board.cpp
字号:
/** board.cpp*/#include <vector>#include "config.h"#include "setting.h"#include "qgo.h"#include "board.h"#include "globals.h"#include "mark.h"#include "imagehandler.h"#include "stonehandler.h"#include "tip.h"#include "interfacehandler.h"#include "move.h"#include "scoretools_gui.h"#include "normaltools_gui.h"#include "mainwindow.h"#include "noderesults.h"#include <qmessagebox.h>#include <qapplication.h>#include <qclipboard.h>#include <qpainter.h>#include <qgroupbox.h>#include <qlineedit.h>#include <qcursor.h>Board::Board(QWidget *parent, const char *name, QCanvas* c): QCanvasView(c, parent, name){ viewport()->setMouseTracking(TRUE); board_size = DEFAULT_BOARD_SIZE; showCoords = setting->readBoolEntry("BOARD_COORDS"); showSGFCoords = setting->readBoolEntry("SGF_BOARD_COORDS"); antiClicko = setting->readBoolEntry("ANTICLICKO"); // Create a BoardHandler instance. boardHandler = new BoardHandler(this); CHECK_PTR(boardHandler); // Create an ImageHandler instance. imageHandler = new ImageHandler(); CHECK_PTR(imageHandler); // Init the canvas canvas = new QCanvas(this, "MainCanvas"); CHECK_PTR(canvas); canvas->setDoubleBuffering(TRUE); canvas->resize(BOARD_X, BOARD_Y); setCanvas(canvas); gatter = new Gatter(canvas, board_size); // Init data storage for marks and ghosts marks = new QPtrList<Mark>; marks->setAutoDelete(TRUE); lastMoveMark = NULL; ghosts = new QList<Stone>; ghosts->setAutoDelete(TRUE); // Init the gatter size and the imagehandler pixmaps calculateSize(); imageHandler->init(square_size); // Initialize some class variables nodeResultsDlg = NULL; fastLoad = false; isModified = false; mouseState = NoButton; for (int i=0; i<400; i++) { if (i < 52) letterPool[i] = false; numberPool[i] = false; } //coordsTip = new Tip(this);#ifdef Q_WS_WIN resizeDelayFlag = false;#endif curX = curY = -1; showCursor = setting->readBoolEntry("CURSOR"); isLocalGame = true; // Init the ghost cursor stone curStone = new Stone(imageHandler->getGhostPixmaps(), canvas, stoneBlack, 0, 0); curStone->setZ(4); curStone->hide(); lockResize = false; navIntersectionStatus = false; updateCaption(); gatter_created = false; isHidingStones = false; // QQQ}Board::~Board(){// delete coordsTip; delete curStone; delete boardHandler; marks->clear(); delete marks; ghosts->clear(); delete ghosts; delete lastMoveMark; delete canvas; delete nodeResultsDlg; delete imageHandler;} void Board::calculateSize(){ // Calculate the size values const int margin = 1, // distance from table edge to wooden board edge w = canvas->width() - margin * 2, h = canvas->height() - margin * 2; int table_size = (w < h ? w : h ); offset = table_size * 2/100 ; // distance from edge of wooden board to playing area (grids + space for stones on 1st & last line) QCanvasText *coordV = new QCanvasText(QString::number(board_size), canvas); QCanvasText *coordH = new QCanvasText("A", canvas); int coord_width = coordV->boundingRect().width(); int coord_height = coordH->boundingRect().height(); // space for coodinates if shown int coord_offset = (coord_width < coord_height ? coord_height : coord_width); if (showCoords) offset = coord_offset + 2 ; //we need 1 more virtual 'square' for the stones on 1st and last line getting off the grid square_size = (table_size - 2*offset) / (board_size); //square_size = (w < h ? (w-2*offset) / (board_size-1) : (h-2*offset) / (board_size-1)); // Should not happen, but safe is safe. if (square_size == 0) square_size = 1; board_pixel_size = square_size * (board_size-1); // grid size offset = (table_size - board_pixel_size)/2; // Center the board in canvas offsetX = margin + (w - board_pixel_size) / 2; offsetY = margin + (h - board_pixel_size) / 2;}void Board::resizeBoard(int w, int h){ if (w < 30 || h < 30) return; Move *m_save = boardHandler->getTree()->getCurrent(); boardHandler->gotoFirstMove(); // Clear background before canvas is resized canvas->setBackgroundPixmap(*(ImageHandler::getTablePixmap(setting->readEntry("SKIN_TABLE")))); // Resize canvas canvas->resize(w, h); // Recalculate the size values calculateSize(); // Rescale the pixmaps in the ImageHandler imageHandler->rescale(square_size);//, setting->readBoolEntry("SMALL_STONES")); // Delete gatter lines and update stones positions QCanvasItemList list = canvas->allItems(); QCanvasItem *item; QCanvasItemList::Iterator it; for(it = list.begin(); it != list.end(); ++it) { item = *it; if (item->rtti() == 3)// || item->rtti() == 6)// || item->rtti() == 7) { item->hide(); delete item; } else if (item->rtti() == RTTI_STONE) { Stone *s = (Stone*)item; s->setX(offsetX + square_size * (s->posX() - 1)); s->setY(offsetY + square_size * (s->posY() - 1)); } else if (item->rtti() >= RTTI_MARK_SQUARE && item->rtti() <= RTTI_MARK_TERR) { Mark *m; switch(item->rtti()) { case RTTI_MARK_SQUARE: m = (MarkSquare*)item; break; case RTTI_MARK_CIRCLE: m = (MarkCircle*)item; m->setSmall(setting->readBoolEntry("SMALL_MARKS")); break; case RTTI_MARK_TRIANGLE: m = (MarkTriangle*)item; break; case RTTI_MARK_CROSS: m = (MarkCross*)item; break; case RTTI_MARK_TEXT: m = (MarkText*)item; break; case RTTI_MARK_NUMBER: m = (MarkNumber*)item; break; case RTTI_MARK_TERR: m = (MarkTerr*)item; break; default: continue; } m->setSize((double)square_size, (double)square_size); m->setX((double)offsetX + (double)square_size * ((double)(m->posX()) - 1.0) - (double)m->getSizeX()/2.0); m->setY((double)offsetY + (double)square_size * ((double)(m->posY()) - 1.0) - (double)m->getSizeY()/2.0); } } boardHandler->gotoMove(m_save); // Redraw the board drawBackground(); drawGatter(); if (showCoords) drawCoordinates(); // Redraw the mark on the last played stone updateLastMove(m_save->getColor(), m_save->getX(), m_save->getY()); //SL added eb 7 // canvas->update();}void Board::resizeEvent(QResizeEvent*){#ifdef _WS_WIN_x if (!resizeDelayFlag) { resizeDelayFlag = true; // not necessary? QTimer::singleShot(50, this, SLOT(changeSize())); }#else if (!lockResize) changeSize();#endif}void Board::drawBackground(){ int w = canvas->width(), h = canvas->height(); // Create pixmap of appropriate size QPixmap all(w, h); // Paint table and board on the pixmap QPainter painter; //QBrush board;// board.setPixmap(*(ImageHandler::getBoardPixmap(static_cast<skinType>(setting->readIntEntry("SKIN"))))); //board.setPixmap(*(ImageHandler::getBoardPixmap(setting->readEntry("SKIN")))); //QBrush table; // table.setPixmap(*(imageHandler->getTablePixmap())); //table.setPixmap(*(ImageHandler::getTablePixmap())); //painter.flush(); painter.begin(&all); painter.setPen(NoPen); //painter.fillRect(0, 0, w, h, table); painter.drawTiledPixmap (0, 0, w, h,*(ImageHandler::getTablePixmap(setting->readEntry("SKIN_TABLE")))); //painter.fillRect( painter.drawTiledPixmap ( offsetX - offset, offsetY - offset, board_pixel_size + offset*2, board_pixel_size + offset*2, *(ImageHandler::getBoardPixmap(setting->readEntry("SKIN")))); painter.end(); QImage image = all.convertToImage(); int lighter=20; int darker=60; int width = 3; int x,y; for(x=0;x<width;x++) for (y= offsetY - offset +x ; y<offsetY + board_pixel_size + offset-x ;y++) { image.setPixel( offsetX - offset+x , y, QColor(image.pixel(offsetX - offset+x,y)).dark(int(100 + darker*(width-x)*(width-x)/width/width)).rgb()); image.setPixel( offsetX + board_pixel_size + offset-x -1, y, QColor(image.pixel(offsetX + board_pixel_size + offset-x-1,y)).light(100+ int(lighter*(width-x)*(width-x)/width/width)).rgb()); } for(y=0;y<width;y++) for (x= offsetX - offset +y ; x<offsetX + board_pixel_size + offset-y ;x++) { image.setPixel( x, offsetY - offset+y , QColor(image.pixel(x,offsetY - offset+y)).light(int(100 + lighter*(width-y)*(width-y)/width/width)).rgb()); image.setPixel( x, offsetY + board_pixel_size + offset-y -1, QColor(image.pixel(x,offsetY + board_pixel_size + offset-y-1)).dark(100+ int(darker*(width-y)*(width-y)/width/width)).rgb()); } width = 10; darker=50; for(x=0;(x<=width)&&(offsetX - offset-x >0) ;x++) for (y= offsetY - offset+x ; (y<offsetY + board_pixel_size + offset+x)&&(y<h) ;y++) { image.setPixel( offsetX - offset-1-x , y, QColor(image.pixel(offsetX - offset-1-x,y)).dark(int(100 + darker*(width-x)/width)).rgb()); } for(y=0;(y<=width)&&(offsetY + board_pixel_size + offset+y+1<h);y++) for (x= (offsetX - offset - y > 0 ? offsetX - offset - y:0) ; x<offsetX + board_pixel_size + offset-y ;x++) { image.setPixel( x, offsetY + board_pixel_size + offset+y +1, QColor(image.pixel(x,offsetY + board_pixel_size + offset+y+1)).dark(100+ int(darker*(width-y)/width)).rgb()); } all.convertFromImage(image); // Set pixmap as canvas background canvas->setBackgroundPixmap(all);}void Board::drawGatter(){/* QCanvasLine *line; int i,j; static QCanvasLine *VGatter[361]; static QCanvasLine *HGatter[361]; // Draw vertical lines for (i=0; i<board_size; i++) { line = new QCanvasLine(canvas); line->setPoints(offsetX + square_size * i, offsetY, offsetX + square_size * i, offsetY + board_pixel_size); line->show(); } // Draw horizontal lines for (i=0; i<board_size; i++) { line = new QCanvasLine(canvas); line->setPoints(offsetX, offsetY + square_size * i, offsetX + board_pixel_size, offsetY + square_size * i); line->show(); } */ gatter->resize(offsetX,offsetY,square_size);/* // Draw the little circles on the starpoints int edge_dist = (board_size > 12 ? 4 : 3); int low = edge_dist; int middle = (board_size + 1) / 2; int high = board_size + 1 - edge_dist; if (board_size % 2 && board_size > 9) { drawStarPoint(middle, low); drawStarPoint(middle, high); drawStarPoint(low, middle); drawStarPoint(high, middle); drawStarPoint(middle, middle); } drawStarPoint(low, low); drawStarPoint(low, high); drawStarPoint(high, low); drawStarPoint(high, high);*/ updateCanvas();}void Board::drawStarPoint(int x, int y){ int size = square_size / 5; // Round size top be even if (size % 2 > 0) size--; if (size < 6) size = 6; QCanvasEllipse *circle; circle = new QCanvasEllipse(canvas); circle->setBrush(black); circle->setSize(size, size); circle->setX(offsetX + square_size * (x-1)); circle->setY(offsetY + square_size * (y-1)); circle->show();} void Board::drawCoordinates(){ QCanvasText *coord; int i; //const int off = 2, const int coord_centre = (offset - square_size/2 )/2; // centres the coordinates text within the remaining space at table edge QString txt; // Draw vertical coordinates. Numbers for (i=0; i<board_size; i++) { // Left side if(showSGFCoords) txt = QString(QChar(static_cast<const char>('a' + i))); else txt = QString::number(board_size - i); coord = new QCanvasText(txt, canvas); coord->setX(offsetX - offset + coord_centre - coord->boundingRect().width()/2 ); coord->setY(offsetY + square_size * i - coord->boundingRect().height()/2); coord->show(); // Right side coord = new QCanvasText(txt, canvas); coord->setX(offsetX + board_pixel_size + offset - coord_centre - coord->boundingRect().width()/2 ); coord->setY(offsetY + square_size * i - coord->boundingRect().height()/2); coord->show(); } // Draw horizontal coordinates. Letters (Note: Skip 'i') for (i=0; i<board_size; i++) { if(showSGFCoords) txt = QString(QChar(static_cast<const char>('a' + i))); else txt = QString(QChar(static_cast<const char>('A' + (i<8?i:i+1)))); // Top coord = new QCanvasText(txt, canvas); coord->setX(offsetX + square_size * i - coord->boundingRect().width()/2); coord->setY(offsetY - offset + coord_centre - coord->boundingRect().height()/2 ); coord->show(); // Bottom coord = new QCanvasText(txt, canvas); coord->setX(offsetX + square_size * i - coord->boundingRect().width()/2); coord->setY(offsetY + offset + board_pixel_size - coord_centre - coord->boundingRect().height()/2 ); coord->show(); }}void Board::hideStones() // QQQ{ isHidingStones ^= true; QIntDict<Stone>* stones = boardHandler->getStoneHandler()->getAllStones(); if (stones->isEmpty()) return; QIntDictIterator<Stone> it(*stones); Stone *s; while (s = it.current()) { if (isHidingStones) { s->setFrame(1+WHITE_STONES_NB+1); s->shadow->setFrame(1+WHITE_STONES_NB+1); } else { if (boardHandler->getGameData()->oneColorGo) s->setFrame((rand() % 8) + 1); else s->setFrame(s->getColor() == stoneBlack ? 0 : (rand() % 8) + 1); s->shadow->setFrame(1+WHITE_STONES_NB); } ++it; } updateCanvas();}Stone* Board::addStoneSprite(StoneColor c, int x, int y, bool &shown){ if (x < 1 || x > board_size || y < 1 || y > board_size) { qWarning("Board::addStoneSprite() - Invalid stone: %d %d", x, y); return NULL; } switch (boardHandler->hasStone(x, y)) { case 1: // Stone exists and is visible // qDebug("*** Already a stone at %d, %d.", x, y); if (boardHandler->display_incoming_move) return NULL; else // we are observig a game, and we are just observing a sone that is // taken later. A new incoming stone is played there. // Ok, this is BAD. { Stone *s = boardHandler->getStoneHandler()->getStoneAt(x, y); CHECK_PTR(s); s->setColor(c); s->setPos(x, y); return s; } case 0: // No stone existing. Create a new one { // qDebug("*** Did not find any stone at %d, %d.", x, y); Stone *s = new Stone(imageHandler->getStonePixmaps(), canvas, c, x, y,WHITE_STONES_NB,true); if (isHidingStones) { // QQQ s->setFrame(1+WHITE_STONES_NB+1); s->shadow->setFrame(1+WHITE_STONES_NB+1); } else { if (boardHandler->getGameData()->oneColorGo) s->toggleOneColorGo(true); else s->setFrame(c == stoneBlack ? 0 : (rand() % 8) + 1); s->shadow->setFrame(1+WHITE_STONES_NB); } CHECK_PTR(s); s->setX(offsetX + square_size * (x-1)); s->setY(offsetY + square_size * (y-1)); // Change color of a mark on this spot to white, if we have a black stone if (c == stoneBlack) updateMarkColor(stoneBlack, x, y); return s; } break; case -1: // Stone exists, but is hidden. Show it and check correct color { Stone *s = boardHandler->getStoneHandler()->getStoneAt(x, y); CHECK_PTR(s); // qDebug("*** Found a hidden stone at %d, %d (%s).", x, y, // Check if the color is correct if (s->getColor() != c) s->setColor(c); s->setPos(x, y); s->show(); shown = true; // Change color of a mark on this spot to white, if we have a black stone if (c == stoneBlack) updateMarkColor(stoneBlack, x, y); return s; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -