00001 #include "canvas.h"
00002
00003 int Canvas::STEP_UP = -3;
00004 int Canvas::STEP_DOWN = 3;
00005
00006 Canvas::Canvas(QWidget *parent)
00007 : QWidget(parent), painter(new QPainter(this)), HMARGIN(0), brcktVmargin(0), x0(0), y0(0), dx(0), dy(0), animated(false), colorStep(0), picks(true)
00008 {
00009 timer = new QTimer(this);
00010 connect(timer, SIGNAL(timeout()), this, SLOT(animate()));
00011
00012 undecided = QPen(Qt::white, 1.5, Qt::CustomDashLine, Qt::RoundCap);
00013 undecided.setDashPattern(QVector<qreal> (2,3));
00014 decided = QPen(QColor(150,150,150), 1.5, Qt::SolidLine, Qt::RoundCap);
00015 }
00016
00017 Canvas::~Canvas()
00018 {
00019 delete timer;
00020 delete painter;
00021 delete tournament;
00022 }
00023
00024 void Canvas::init(void)
00025 {
00026
00027 pen = QPen(Qt::white, 1.5, Qt::CustomDashLine, Qt::RoundCap);
00028 pen.setDashPattern(QVector<qreal> (2,3));
00029
00030 HMARGIN = width()/6;
00031 brcktVmargin = 50;
00032
00033 x0 = HMARGIN+brcktHmargin;
00034 y0 = VMARGIN;
00035 dx = floor((double)((width()/2-HMARGIN-brcktHmargin)/((log((double)tournament->getTeamCount())/log(2.0)-1))));
00036 dy = floor((double)((height()-2*VMARGIN-(tournament->getBracketCount()-1)*brcktVmargin)/tournament->getBracketCount()));
00037
00038 initBracketPositions(tournament->getTeamCount()-2, tournament->getBracketCount(),y0,dy,0);
00039 }
00040
00041 void Canvas::initBracketPositions(int id, int num, int y0, int dy, int level)
00042 {
00043 int ylink;
00044 int h = floor((double)(y0+dy/2));
00045
00046 for (int i=0; i<num; i++)
00047 {
00048 ylink = floor((double)(y0+dy/2));
00049 tournament->getGameByID(id-i)->setBracket(y0,dy,ylink,level,Canvas::LEFT,3,pen);
00050 tournament->getGameByID(id-i-num)->setBracket(y0,dy,ylink,level,Canvas::RIGHT,-3,undecided);
00051 y0 += dy+brcktVmargin;
00052 }
00053
00054 y0 = h;
00055 dy += brcktVmargin;
00056 brcktVmargin = dy;
00057
00058 if (num!=1)
00059 initBracketPositions((id-2)/2,num/2, y0, dy, ++level);
00060 }
00061
00062 void Canvas::resizeEvent(QResizeEvent* revent)
00063 {
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 }
00090
00091 void Canvas::paintEvent(QPaintEvent* pevent)
00092 {
00093 painter->begin(this);
00094 painter->setRenderHint(QPainter::Antialiasing, true);
00095 fontheight = painter->fontMetrics().height()/2;
00096
00097 if(picks)
00098 drawPicks(round);
00099 drawTeamInfo();
00100 drawBrackets();
00101
00102 painter->end();
00103 }
00104
00105 QPainterPath Canvas::drawBracket(int x0, int y0, int ylink, int dx, int dy, int dashOffset)
00106 {
00107 int ym = floor((double)(y0+dy/2));
00108 dx/= 2;
00109
00110 QPainterPath path;
00111 path.moveTo(x0,y0);
00112 path.cubicTo(x0+dx,y0,x0+dx,y0,x0+dx,ym-abs(ym-ylink));
00113 path.lineTo(x0+dx,ym+abs(ym-ylink));
00114 path.cubicTo(x0+dx,y0+dy,x0+dx,y0+dy,x0,y0+dy);
00115 path.moveTo(x0+dx+dashOffset,ylink);
00116 path.lineTo(x0+2*dx,ylink);
00117
00118 return path;
00119 }
00120
00121 void Canvas::drawBrackets(void)
00122 {
00123 QVector<Game*> games = tournament->getGames();
00124 for (int i=0; i<games.size()-1; i++)
00125 {
00126 Game::Bracket bracket = games[i]->getBracket();
00127
00128 if(bracket.dir == Canvas::LEFT)
00129 x0 = HMARGIN+brcktHmargin;
00130 else
00131 x0 = width()-HMARGIN-brcktHmargin;
00132
00133 painter->setPen(bracket.pen);
00134 painter->drawPath(drawBracket(x0+dx*bracket.level*bracket.dir, bracket.y0, bracket.ylink, dx*bracket.dir, bracket.dy, bracket.dashOffset));
00135
00136 if(isDrawn(games[i]) && !games[i]->getTeam(games[i]->getState())->hasLost())
00137 {
00138 painter->setPen(QPen(Qt::white, 4, Qt::SolidLine, Qt::RoundCap));
00139 painter->drawLine(x0, bracket.ylink, x0+dx*(bracket.level+1)*bracket.dir, bracket.ylink);
00140 }
00141 }
00142
00143 if(games.last()->getState() && round == tournament->getTeamCount()-1)
00144 painter->setPen(decided);
00145 else
00146 painter->setPen(undecided);
00147 painter->drawLine(width()/2, games[games.size()-2]->getBracket().ylink, width()/2, games[games.size()-3]->getBracket().ylink);
00148 }
00149
00150 void Canvas::drawTeamInfo(void)
00151 {
00152 int cnt = tournament->getBracketCount();
00153 int gameCnt = tournament->getTeamCount()-1;
00154 int currRound = gameCnt-round;
00155 bool draw;
00156
00157 for (int i=0; i<cnt; i++)
00158 {
00159 Game* game = tournament->getGameByID(tournament->getTeamCount()-2-i);
00160 Game::Bracket bracket = game->getBracket();
00161
00162
00163
00164 painter->setPen(getPenForTeam(game->getTeam(1)));
00165 painter->drawText(QRect(QPoint(0, bracket.y0-fontheight), QPoint(HMARGIN-35*!game->getTeam(1)->getIcon().isNull(), bracket.y0+fontheight)),
00166 game->getTeam(1)->getName(), QTextOption(Qt::AlignRight));
00167
00168
00169 painter->drawPixmap(QRect(QPoint(HMARGIN-25, bracket.y0-12), QPoint(HMARGIN, bracket.y0+12)), game->getTeam(1)->getIcon());
00170
00171
00172 painter->setPen(getPenForTeam(game->getTeam(2)));
00173 painter->drawText(QRect(QPoint(0, bracket.y0+bracket.dy-fontheight), QPoint(HMARGIN-35*!game->getTeam(2)->getIcon().isNull(), bracket.y0+bracket.dy+fontheight)),
00174 game->getTeam(2)->getName(), QTextOption(Qt::AlignRight));
00175
00176
00177 painter->drawPixmap(QRect(QPoint(HMARGIN-25, bracket.y0+bracket.dy-12), QPoint(HMARGIN, bracket.y0+bracket.dy+12)), game->getTeam(2)->getIcon());
00178
00179 game = tournament->getGameByID(tournament->getTeamCount()-tournament->getBracketCount()-2-i);
00180 bracket = game->getBracket();
00181
00182
00183
00184 painter->setPen(getPenForTeam(game->getTeam(1)));
00185 painter->drawText(QRect(QPoint(width()-HMARGIN+35*!game->getTeam(1)->getIcon().isNull(), bracket.y0-fontheight), QPoint(width(), bracket.y0+fontheight)),
00186 game->getTeam(1)->getName(), QTextOption(Qt::AlignLeft));
00187 painter->drawPixmap(QRect(QPoint(width()-HMARGIN, bracket.y0-12), QPoint(width()-HMARGIN+25, bracket.y0+12)), game->getTeam(1)->getIcon());
00188
00189
00190 painter->setPen(getPenForTeam(game->getTeam(2)));
00191 painter->drawText(QRect(QPoint(width()-HMARGIN+35*!game->getTeam(2)->getIcon().isNull(), bracket.y0+bracket.dy-fontheight), QPoint(width(), bracket.y0+bracket.dy+fontheight)),
00192 game->getTeam(2)->getName(), QTextOption(Qt::AlignLeft));
00193 painter->drawPixmap(QRect(QPoint(width()-HMARGIN, bracket.y0+bracket.dy-12), QPoint(width()-HMARGIN+25, bracket.y0+bracket.dy+12)), game->getTeam(2)->getIcon());
00194 }
00195 }
00196
00197 QPen Canvas::getPenForTeam(Team *team)
00198 {
00199 if(team->hasLost())
00200 return decided;
00201 else
00202 return undecided;
00203 }
00204
00205
00206 void Canvas::drawPicks(int round)
00207 {
00208 painter->setPen(Qt::NoPen);
00209
00210 QBrush brush;
00211 QPixmap pix("Resources/strip.png");
00212
00213 int pickLength=dx/2;
00214
00215 Team::Round minR = tournament->getMinRound();
00216
00217 int mult = 1, x, y;
00218 int dir = 1;
00219 int tcnt = tournament->getTeamCount();
00220 int length = normalLen;
00221 int gameCnt = tcnt-1;
00222 int currRound = gameCnt-round;
00223
00224
00225 for(int i=tcnt-2; i>=tcnt/2-1; i--)
00226 {
00227 Game* currGame = tournament->getGameByID(i);
00228
00229 Team::Round r[2];
00230 r[0] = currGame->getTeam1Direct()->getPick();
00231 r[1] = currGame->getTeam2Direct()->getPick();
00232
00233 Game::Bracket bracket = currGame->getBracket();
00234
00235 if(bracket.dir == Canvas::LEFT)
00236 x0 = HMARGIN+brcktHmargin;
00237 else
00238 x0 = width()-HMARGIN-brcktHmargin;
00239
00240
00241 for(int j=0; j<2; j++)
00242 {
00243 if(j==0) mult = 0;
00244 else mult = 1;
00245
00246 if(bracket.dir==-1)
00247 {
00248 length = pickLength*2*-1;
00249 x=x0-dx/4;
00250 }
00251 else
00252 {
00253 length = pickLength*2;
00254 x = x0+dx/4;
00255 }
00256
00257 y = bracket.y0+mult*dy-pickHeight/2;
00258
00259
00260 brush = QBrush(Qt::green, Qt::SolidPattern);
00261 painter->setBrush(brush);
00262 painter->drawRoundedRect(QRect(x-10,y,15,pickHeight),5,5,Qt::AbsoluteSize);
00263
00264 int rNumber = r[j]-minR+1;
00265 QVector<bool> played;
00266 Game* temp = currGame;
00267
00268 for(int l=0; l<rNumber; l++)
00269 {
00270 if(currRound-1<temp->getID() && temp->getState()!=Game::UNDECIDED)
00271 {
00272 played.append(true);
00273 }
00274 else
00275 played.append(false);
00276
00277 if(temp->getID()%2==0)
00278 temp = tournament->getGameByID(temp->getID()/2-1);
00279 else
00280 temp = tournament->getGameByID(temp->getID()/2);
00281 }
00282
00283 int tL;
00284
00285 temp = currGame;
00286 bool wrongBet = false;
00287
00288
00289 for(int k=minR; k<=r[j]; k++) {
00290 if(rNumber>0)
00291 {
00292 int t1=1, t2=2;
00293 if(temp->getTeam1()!= currGame->getTeam1())
00294 {
00295 t1 = 2;
00296 t2 = 1;
00297 }
00298
00299 if(played[k-minR])
00300 {
00301 if((j==0 && t1==1 && temp->getState()==Game::WINTEAM1)
00302 || (j==0 && t1==2 && temp->getState()==Game::WINTEAM2)
00303 || (j==1 && t2==1 && temp->getState()==Game::WINTEAM1)
00304 || (j==1 && t2==2 && temp->getState()==Game::WINTEAM2)) {
00305 brush = QBrush(Qt::green, Qt::SolidPattern);
00306 painter->setBrush(brush);
00307 }
00308 else
00309 {
00310 brush = QBrush(Qt::red, Qt::SolidPattern);
00311 painter->setBrush(brush);
00312 }
00313 if((j==0 && t1==1 && temp->getState()==Game::WINTEAM2)
00314 || (j==0 && t1==2 && temp->getState()==Game::WINTEAM1)
00315 || (j==1 && t2==1 && temp->getState()==Game::WINTEAM2)
00316 || (j==1 && t2==2 && temp->getState()==Game::WINTEAM1)) {
00317 wrongBet = true;
00318 }
00319 }
00320 else
00321 {
00322 brush = QBrush(Qt::green,pix);
00323 painter->setBrush(brush);
00324 }
00325 if(wrongBet)
00326 {
00327 brush = QBrush(Qt::red, Qt::SolidPattern);
00328 painter->setBrush(brush);
00329 }
00330 }
00331
00332 if(k==minR)
00333 {
00334 tL = length;
00335 if(bracket.dir==-1)
00336 {
00337 length = length-dx/4;
00338 }
00339 else
00340 {
00341 length = length+dx/4;
00342 }
00343 }
00344 else length = tL;
00345
00346
00347 if(k==Team::HALF) length=length/3;
00348 if(k==Team::FINAL) length = length/5;
00349 painter->drawRect(x,y,length,pickHeight);
00350 x = x+length;
00351 if(temp->getID()%2==0)
00352 temp = tournament->getGameByID(temp->getID()/2-1);
00353 else
00354 temp = tournament->getGameByID(temp->getID()/2);
00355 }
00356 }
00357 }
00358
00359
00360 painter->setBrush(Qt::NoBrush);
00361
00362 pen = QPen(Qt::white, 1.5, Qt::CustomDashLine, Qt::RoundCap);
00363 pen.setDashPattern(QVector<qreal> (2,3));
00364 painter->setPen(pen);
00365 }
00366
00367 void Canvas::mousePressEvent(QMouseEvent* mevent)
00368 {
00369 int x = mevent->globalX();
00370 int y = mevent->globalY();
00371 Qt::MouseButton button = mevent->button();
00372
00373 Team* t = findTeamFromCoordinates(x,y);
00374
00375 if(t!=0)
00376 {
00377 qDebug("Team clicked: %i", t->getId());
00378 Team::Round r = t->getPick();
00379 if(button==Qt::LeftButton)
00380 {
00381 if(r==Team::NO)
00382 t->setPick(tournament->getMinRound());
00383 else if(r!=Team::FINAL)
00384 {
00385 r = Team::getPickForInt(r+1);
00386 t->setPick(r);
00387 }
00388
00389 }
00390 else
00391 {
00392 if(r!=Team::NO)
00393 {
00394 r = Team::getPickForInt(r-1);
00395 t->setPick(r);
00396 }
00397 }
00398
00399 }
00400 update();
00401 }
00402
00403 Team* Canvas::findTeamFromCoordinates(int x, int y)
00404 {
00405 int bar = 72;
00406 int sizeVert = 10;
00407 int sizeHor = 10;
00408
00409 QVector<Game*> games = this->tournament->getGames();
00410 int currXLow;
00411 int currXHigh;
00412 int currYLow;
00413 int currYHigh;
00414 Game::Bracket bracket;
00415
00416 for(int i=0; i<games.size(); i++)
00417 {
00418 bracket = games[i]->getBracket();
00419 if(bracket.dir == Canvas::LEFT)
00420 x0 = HMARGIN+brcktHmargin+dx/4;
00421 else
00422 x0 = width()-HMARGIN-brcktHmargin-dx/4;
00423
00424 currXLow = x0-sizeHor;
00425 currXHigh = x0+sizeHor;
00426 currYLow = bracket.y0-sizeVert+bar;
00427 currYHigh = bracket.y0+sizeVert+bar;
00428
00429 if(x>currXLow && x<currXHigh
00430 && y>currYLow && y<currYHigh)
00431 {
00432 return games[i]->getTeam1Direct();
00433 }
00434
00435 currYLow = currYLow + bracket.dy;
00436 currYHigh = currYHigh + bracket.dy;
00437
00438 if(x>currXLow && x<currXHigh
00439 && y>currYLow && y<currYHigh)
00440 {
00441 return games[i]->getTeam2Direct();
00442 }
00443 }
00444 return 0;
00445 }
00446
00447
00448 void Canvas::updateParentBracket(int ID)
00449 {
00450 if(ID != 0)
00451 {
00452 Game* game = tournament->getGameByID(ID);
00453 Game::Bracket left = game->getChild(Game::LEFTCHILD)->getBracket();
00454 Game::Bracket right = game->getChild(Game::RIGHTCHILD)->getBracket();
00455 game->setBracket(left.ylink, right.ylink-left.ylink, left.ylink+floor((double)(right.ylink-left.ylink)/2), game->getBracket().dashOffset);
00456 updateParentBracket((ID-2+ID%2)/2);
00457 }
00458 }
00459
00460 bool Canvas::isDrawn(Game *game)
00461 {
00462 Game::Bracket bracket = game->getBracket();
00463 if(bracket.ylink == bracket.y0 || bracket.ylink == bracket.y0+bracket.dy)
00464 return true;
00465 else
00466 return false;
00467 }
00468
00469
00470 void Canvas::setAnimationEndPoint(int end, int offset, int color)
00471 {
00472 animEnd = end;
00473 dashOffset = offset;
00474 colorStep = color;
00475 }
00476
00477 void Canvas::animate()
00478 {
00479 Game::Bracket bracket = animatedGame->getBracket();
00480 int ID = animatedGame->getID();
00481
00482 if(ID != 0)
00483 {
00484 if(abs(bracket.ylink-animEnd)>STEP_DOWN)
00485 {
00486 int color = bracket.pen.color().green();
00487 if(isDrawn(animatedGame))
00488 {
00489 bracket.pen = undecided;
00490 colorStep = -colorStep;
00491 }
00492 color = std::max(std::min(color-colorStep, 255), 150);
00493 animatedGame->setBracket(bracket.y0, bracket.dy, bracket.ylink+step, dashOffset);
00494 bracket.pen.setColor(QColor(color,color,color));
00495 animatedGame->setPen(bracket.pen);
00496 updateParentBracket((ID-2+ID%2)/2);
00497 }
00498
00499 else
00500 {
00501 animatedGame->setBracket(bracket.y0, bracket.dy, animEnd, dashOffset);
00502 updateParentBracket((ID-2+ID%2)/2);
00503 timer->stop();
00504 animated = false;
00505 if(isDrawn(animatedGame))
00506 animatedGame->setPen(decided);
00507 else
00508 animatedGame->setPen(undecided);
00509 }
00510 update();
00511 }
00512
00513 else
00514 {
00515 timer->stop();
00516 animated = false;
00517 }
00518 }