📄 editor.cpp
字号:
i18n("Save board layout." )); if (res != KMessageBox::Yes) return false; } bool result = theBoard.saveBoardLayout( url.path() ); if (result==true){ clean = true; return true; } else { return false; }}// test if a save is required and return true if the app is to continue// false if cancel is selected. (if ok then call out to save the boardbool Editor::testSave(void) { if (clean) return(true); int res; res=KMessageBox::warningYesNoCancel(this, i18n("The board has been modified, would you" "like to save the changes?")); if (res == KMessageBox::Yes) { // yes to save if (saveBoard()) { return true; } else { KMessageBox::sorry(this, i18n("Save failed. Aborting operation.")); } } else { return (res != KMessageBox::Cancel); } return(true);}// The main paint event, draw in the grid and blit in // the tiles as specified by the layout.void Editor::paintEvent( QPaintEvent* ) { // first we layer on a background grid QPixmap buff; QPixmap *dest=drawFrame->getPreviewPixmap(); buff.resize(dest->width(), dest->height()); drawBackground(&buff); drawTiles(&buff); bitBlt(dest, 0,0,&buff, 0,0,buff.width(), buff.height(), CopyROP); drawFrame->repaint(false);}void Editor::drawBackground(QPixmap *pixmap) { QPainter p(pixmap); // blast in a white background p.fillRect(0,0,pixmap->width(), pixmap->height(), QColor(white)); // now put in a grid of tile quater width squares int sy = (tiles.height()/2)+tiles.shadowSize(); int sx = (tiles.width()/2); for (int y=0; y<=BoardLayout::height; y++) { int nextY=sy+(y*tiles.qHeight()); p.drawLine(sx, nextY,sx+(BoardLayout::width*tiles.qWidth()), nextY); } for (int x=0; x<=BoardLayout::width; x++) { int nextX=sx+(x*tiles.qWidth()); p.drawLine(nextX, sy, nextX, sy+BoardLayout::height*tiles.qHeight()); }}void Editor::drawTiles(QPixmap *dest) { QPainter p(dest); // blast in a white background tiles.loadTileset(preferences.tileset()); int xOffset = tiles.width()/2; int yOffset = tiles.height()/2; short tile = 0; // we iterate over the depth stacking order. zach sucessive level is // drawn one indent up and to the right. The indent is the width // of the 3d relief on the tile left (tile shadow width) for (int z=0; z<BoardLayout::depth; z++) { // we draw down the board so the tile below over rights our border for (int y = 0; y < BoardLayout::height; y++) { // drawing right to left to prevent border overwrite for (int x=BoardLayout::width-1; x>=0; x--) { int sx = x*(tiles.qWidth() )+xOffset; int sy = y*(tiles.qHeight() )+yOffset; if (theBoard.getBoardData(z, y, x) != '1') { continue; } QPixmap *t; tile=(z*BoardLayout::depth)+ (y*BoardLayout::height)+ (x*BoardLayout::width);// if (mode==remove && currPos.x==x && currPos.y==y && currPos.e==z) {// t = tiles.selectedPixmaps(44));// } else { t = tiles.unselectedPixmaps(43);// } // Only one compilcation. Since we render top to bottom , left // to right situations arise where...: // there exists a tile one q height above and to the left // in this situation we would draw our top left border over it // we simply split the tile draw so the top half is drawn // minus border if ((x>1) && (y>0) && theBoard.getBoardData(z,y-1,x-2)=='1'){ bitBlt( dest, sx+tiles.shadowSize(), sy, t, tiles.shadowSize() ,0, t->width()-tiles.shadowSize(), t->height()/2, CopyROP ); bitBlt( dest, sx, sy+t->height()/2, t, 0,t->height()/2,t->width(),t->height()/2,CopyROP); } else { bitBlt( dest, sx, sy, t, 0,0, t->width(), t->height(), CopyROP ); } tile++; tile = tile % 143; } } xOffset +=tiles.shadowSize(); yOffset -=tiles.shadowSize(); } }// convert mouse position on screen to a tile z y x coord// different to the one in kmahjongg.cpp since if we hit ground// we return a result too.void Editor::transformPointToPosition( const QPoint& point, POSITION& MouseClickPos, bool align) { short z = 0; // shut the compiler up about maybe uninitialised errors short y = 0; short x = 0; MouseClickPos.e = 100; // iterate over z coordinate from top to bottom for( z=BoardLayout::depth-1; z>=0; z-- ) { // calculate mouse coordiantes --> position in game board // the factor -theTiles.width()/2 must keep track with the // offset for blitting in the print zvent (FIX ME) x = ((point.x()-tiles.width()/2)-(z+1)*tiles.shadowSize())/ tiles.qWidth(); y = ((point.y()-tiles.height()/2)+ z*tiles.shadowSize()) / tiles.qHeight(); // skip when position is illegal if (x<0 || x>=BoardLayout::width || y<0 || y>=BoardLayout::height) continue; // switch( theBoard.getBoardData(z,y,x) ) { case (UCHAR)'3': if (align) x--;y--; break; case (UCHAR)'2': if (align) x--; break; case (UCHAR)'4': if (align) y--; break; case (UCHAR)'1': break; default : continue; } // if gameboard is empty, skip if ( ! theBoard.getBoardData(z,y,x) ) continue; // here, position is legal MouseClickPos.e = z; MouseClickPos.y = y; MouseClickPos.x = x; MouseClickPos.f = theBoard.getBoardData(z,y,x); break; } if (MouseClickPos.e == 100) { MouseClickPos.x = x; MouseClickPos.y = y; MouseClickPos.f=0; }}// we swallow the draw frames mouse clicks and process herevoid Editor::drawFrameMousePressEvent( QMouseEvent* e ){ POSITION mPos; transformPointToPosition(e->pos(), mPos, (mode == remove)); switch (mode) { case remove: if (!theBoard.tileAbove(mPos) && mPos.e < BoardLayout::depth && theBoard.isTileAt(mPos) ) { theBoard.deleteTile(mPos); numTiles--; statusChanged(); drawFrameMouseMovedEvent(e); repaint(false); } break; case insert: { POSITION n = mPos; if (n.e == 100) n.e = 0; else n.e += 1; if (canInsert(n)) { theBoard.insertTile(n); numTiles++; statusChanged(); repaint(false); } } break; default: break; }} void Editor::drawCursor(POSITION &p, bool visible){ int x = (tiles.width()/2)+(p.e*tiles.shadowSize())+(p.x * tiles.qWidth()); int y = (tiles.height()/2)-(p.e*tiles.shadowSize())+(p.y * tiles.qHeight()); int w = tiles.width(); int h = tiles.height(); if (p.e==100 || !visible) x = -1; drawFrame->setRect(x,y,w,h, tiles.shadowSize(), mode-remove); drawFrame->repaint(false); }// we swallow the draw frames mouse moves and process herevoid Editor::drawFrameMouseMovedEvent( QMouseEvent* e ){ POSITION mPos; transformPointToPosition(e->pos(), mPos, (mode == remove)); if ((mPos.x==currPos.x) && (mPos.y==currPos.y) && (mPos.e==currPos.e)) return; currPos = mPos; statusChanged(); switch(mode) { case insert: POSITION next; next = currPos; if (next.e == 100) next.e = 0; else next.e += 1; drawCursor(next, canInsert(next)); break; case remove: drawCursor(currPos, 1); break; case move: break; }}// can we inser a tile here. We can iff// there are tiles in all positions below us (or we are a ground level)// there are no tiles intersecting with us on this level bool Editor::canInsert(POSITION &p) { if (p.e >= BoardLayout::depth) return (false); if (p.y >BoardLayout::height-2) return false; if (p.x >BoardLayout::width-2) return false; POSITION n = p; if (p.e != 0) { n.e -= 1; if (!theBoard.allFilled(n)) return(false); } return(!theBoard.anyFilled(p));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -