Generated on Thu Mar 22 10:39:32 2012 for Gecode by doxygen 1.6.3

drawingcursor.cpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Guido Tack <tack@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Guido Tack, 2006
00008  *
00009  *  Last modified:
00010  *     $Date: 2010-08-12 09:48:30 +0200 (Thu, 12 Aug 2010) $ by $Author: tack $
00011  *     $Revision: 11345 $
00012  *
00013  *  This file is part of Gecode, the generic constraint
00014  *  development environment:
00015  *     http://www.gecode.org
00016  *
00017  * Permission is hereby granted, free of charge, to any person obtaining
00018  * a copy of this software and associated documentation files (the
00019  * "Software"), to deal in the Software without restriction, including
00020  * without limitation the rights to use, copy, modify, merge, publish,
00021  * distribute, sublicense, and/or sell copies of the Software, and to
00022  * permit persons to whom the Software is furnished to do so, subject to
00023  * the following conditions:
00024  *
00025  * The above copyright notice and this permission notice shall be
00026  * included in all copies or substantial portions of the Software.
00027  *
00028  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00029  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00030  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00031  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00032  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00033  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00034  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00035  *
00036  */
00037 
00038 #include <gecode/gist/drawingcursor.hh>
00039 
00040 namespace Gecode { namespace Gist {
00041 
00043   const QColor DrawingCursor::red(218, 37, 29);
00045   const QColor DrawingCursor::green(11, 118, 70);
00047   const QColor DrawingCursor::blue(0, 92, 161);
00049   const QColor DrawingCursor::orange(235, 137, 27);
00051   const QColor DrawingCursor::white(255,255,255);
00052 
00054   const QColor DrawingCursor::lightRed(218, 37, 29, 120);
00056   const QColor DrawingCursor::lightGreen(11, 118, 70, 120);
00058   const QColor DrawingCursor::lightBlue(0, 92, 161, 120);
00059 
00060   const double nodeWidth = 20.0;
00061   const double halfNodeWidth = nodeWidth / 2.0;
00062   const double quarterNodeWidth = halfNodeWidth / 2.0;
00063   const double failedWidth = 14.0;
00064   const double halfFailedWidth = failedWidth / 2.0;
00065   const double quarterFailedWidthF = failedWidth / 4.0;
00066   const double shadowOffset = 3.0;
00067   const double hiddenDepth =
00068     static_cast<double>(Layout::dist_y) + failedWidth;
00069 
00070   DrawingCursor::DrawingCursor(VisualNode* root,
00071                                const VisualNode::NodeAllocator& na,
00072                                BestNode* curBest0,
00073                                QPainter& painter0,
00074                                const QRect& clippingRect0, bool showCopies)
00075     : NodeCursor<VisualNode>(root,na), painter(painter0),
00076       clippingRect(clippingRect0), curBest(curBest0),
00077       x(0.0), y(0.0), copies(showCopies) {
00078     QPen pen = painter.pen();
00079     pen.setWidth(1);
00080     painter.setPen(pen);
00081   }
00082 
00083   void
00084   DrawingCursor::processCurrentNode(void) {
00085     Gist::VisualNode* n = node();
00086     double parentX = x - static_cast<double>(n->getOffset());
00087     double parentY = y - static_cast<double>(Layout::dist_y) + nodeWidth;
00088     if (!n->isRoot() &&
00089         (n->getParent(na)->getStatus() == STOP ||
00090          n->getParent(na)->getStatus() == UNSTOP) )
00091       parentY -= (nodeWidth-failedWidth)/2;
00092 
00093     double myx = x;
00094     double myy = y;
00095 
00096     if (n->getStatus() == STOP || n->getStatus() == UNSTOP)
00097       myy += (nodeWidth-failedWidth)/2;
00098 
00099     if (n != startNode()) {
00100       if (n->isOnPath())
00101         painter.setPen(Qt::red);
00102       else
00103         painter.setPen(Qt::black);
00104       // Here we use drawPath instead of drawLine in order to
00105       // workaround a strange redraw artefact on Windows
00106       QPainterPath path;
00107       path.moveTo(myx,myy);
00108       path.lineTo(parentX,parentY);
00109       painter.drawPath(path);
00110     }
00111 
00112     // draw shadow
00113     if (n->isMarked()) {
00114       painter.setBrush(Qt::gray);
00115       painter.setPen(Qt::NoPen);
00116       if (n->isHidden()) {
00117         QPointF points[3] = {QPointF(myx+shadowOffset,myy+shadowOffset),
00118                              QPointF(myx+nodeWidth+shadowOffset,
00119                                      myy+hiddenDepth+shadowOffset),
00120                              QPointF(myx-nodeWidth+shadowOffset,
00121                                      myy+hiddenDepth+shadowOffset),
00122                             };
00123         painter.drawConvexPolygon(points, 3);
00124 
00125       } else {
00126         switch (n->getStatus()) {
00127         case Gist::SOLVED:
00128           {
00129             QPointF points[4] = {QPointF(myx+shadowOffset,myy+shadowOffset),
00130                                  QPointF(myx+halfNodeWidth+shadowOffset,
00131                                          myy+halfNodeWidth+shadowOffset),
00132                                  QPointF(myx+shadowOffset,
00133                                          myy+nodeWidth+shadowOffset),
00134                                  QPointF(myx-halfNodeWidth+shadowOffset,
00135                                          myy+halfNodeWidth+shadowOffset)
00136                                 };
00137             painter.drawConvexPolygon(points, 4);
00138           }
00139           break;
00140         case Gist::FAILED:
00141           painter.drawRect(myx-halfFailedWidth+shadowOffset,
00142                            myy+shadowOffset, failedWidth, failedWidth);
00143           break;
00144         case Gist::UNSTOP:
00145         case Gist::STOP:
00146           {
00147             QPointF points[8] = {QPointF(myx+shadowOffset-quarterFailedWidthF,
00148                                          myy+shadowOffset),
00149                                  QPointF(myx+shadowOffset+quarterFailedWidthF,
00150                                          myy+shadowOffset),
00151                                  QPointF(myx+shadowOffset+halfFailedWidth,
00152                                          myy+shadowOffset
00153                                             +quarterFailedWidthF),
00154                                  QPointF(myx+shadowOffset+halfFailedWidth,
00155                                          myy+shadowOffset+halfFailedWidth+
00156                                              quarterFailedWidthF),
00157                                  QPointF(myx+shadowOffset+quarterFailedWidthF,
00158                                          myy+shadowOffset+failedWidth),
00159                                  QPointF(myx+shadowOffset-quarterFailedWidthF,
00160                                          myy+shadowOffset+failedWidth),
00161                                  QPointF(myx+shadowOffset-halfFailedWidth,
00162                                          myy+shadowOffset+halfFailedWidth+
00163                                              quarterFailedWidthF),
00164                                  QPointF(myx+shadowOffset-halfFailedWidth,
00165                                          myy+shadowOffset
00166                                             +quarterFailedWidthF),
00167                                 };
00168             painter.drawConvexPolygon(points, 8);
00169           }
00170           break;
00171         case Gist::BRANCH:
00172           painter.drawEllipse(myx-halfNodeWidth+shadowOffset,
00173                               myy+shadowOffset, nodeWidth, nodeWidth);
00174           break;
00175         case Gist::UNDETERMINED:
00176           painter.drawEllipse(myx-halfNodeWidth+shadowOffset,
00177                               myy+shadowOffset, nodeWidth, nodeWidth);
00178           break;
00179         }
00180       }
00181     }
00182 
00183     painter.setPen(Qt::SolidLine);
00184     if (n->isHidden()) {
00185       if (n->hasOpenChildren()) {
00186         QLinearGradient gradient(myx-nodeWidth,myy,
00187                                  myx+nodeWidth*1.3,myy+hiddenDepth*1.3);
00188         if (n->hasSolvedChildren()) {
00189           gradient.setColorAt(0, white);
00190           gradient.setColorAt(1, green);
00191         } else if (n->hasFailedChildren()) {
00192           gradient.setColorAt(0, white);
00193           gradient.setColorAt(1, red);          
00194         } else {
00195           gradient.setColorAt(0, white);
00196           gradient.setColorAt(1, QColor(0,0,0));
00197         }
00198         painter.setBrush(gradient);
00199       } else {
00200         if (n->hasSolvedChildren())
00201           painter.setBrush(QBrush(green));
00202         else
00203           painter.setBrush(QBrush(red));
00204       }
00205       
00206       QPointF points[3] = {QPointF(myx,myy),
00207                            QPointF(myx+nodeWidth,myy+hiddenDepth),
00208                            QPointF(myx-nodeWidth,myy+hiddenDepth),
00209                           };
00210       painter.drawConvexPolygon(points, 3);
00211     } else {
00212       switch (n->getStatus()) {
00213       case Gist::SOLVED:
00214         {
00215           if (n->isCurrentBest(curBest)) {
00216             painter.setBrush(QBrush(orange));
00217           } else {
00218             painter.setBrush(QBrush(green));
00219           }
00220           QPointF points[4] = {QPointF(myx,myy),
00221                                QPointF(myx+halfNodeWidth,myy+halfNodeWidth),
00222                                QPointF(myx,myy+nodeWidth),
00223                                QPointF(myx-halfNodeWidth,myy+halfNodeWidth)
00224                               };
00225           painter.drawConvexPolygon(points, 4);
00226         }
00227         break;
00228       case Gist::FAILED:
00229         painter.setBrush(QBrush(red));
00230         painter.drawRect(myx-halfFailedWidth, myy, failedWidth, failedWidth);
00231         break;
00232       case Gist::UNSTOP:
00233       case Gist::STOP:
00234         {
00235           painter.setBrush(n->getStatus() == STOP ? 
00236                            QBrush(red) : QBrush(green));
00237           QPointF points[8] = {QPointF(myx-quarterFailedWidthF,myy),
00238                                QPointF(myx+quarterFailedWidthF,myy),
00239                                QPointF(myx+halfFailedWidth,
00240                                        myy+quarterFailedWidthF),
00241                                QPointF(myx+halfFailedWidth,
00242                                        myy+halfFailedWidth+
00243                                            quarterFailedWidthF),
00244                                QPointF(myx+quarterFailedWidthF,
00245                                        myy+failedWidth),
00246                                QPointF(myx-quarterFailedWidthF,
00247                                        myy+failedWidth),
00248                                QPointF(myx-halfFailedWidth,
00249                                        myy+halfFailedWidth+
00250                                            quarterFailedWidthF),
00251                                QPointF(myx-halfFailedWidth,
00252                                        myy+quarterFailedWidthF),
00253                               };
00254           painter.drawConvexPolygon(points, 8);
00255         }
00256         break;
00257       case Gist::BRANCH:
00258         painter.setBrush(n->childrenLayoutIsDone() ? QBrush(blue) : 
00259                                                      QBrush(white));
00260         painter.drawEllipse(myx-halfNodeWidth, myy, nodeWidth, nodeWidth);
00261         break;
00262       case Gist::UNDETERMINED:
00263         painter.setBrush(Qt::white);
00264         painter.drawEllipse(myx-halfNodeWidth, myy, nodeWidth, nodeWidth);
00265         break;
00266       }
00267     }
00268 
00269     if (copies && (n->hasCopy() && !n->hasWorkingSpace())) {
00270      painter.setBrush(Qt::darkRed);
00271      painter.drawEllipse(myx, myy, 10.0, 10.0);
00272     }
00273 
00274     if (copies && n->hasWorkingSpace()) {
00275      painter.setBrush(Qt::darkYellow);
00276      painter.drawEllipse(myx, myy + 10.0, 10.0, 10.0);
00277     }
00278 
00279     if (n->isBookmarked()) {
00280      painter.setBrush(Qt::black);
00281      painter.drawEllipse(myx-10-0, myy, 10.0, 10.0);
00282     }
00283 
00284   }
00285 
00286 }}
00287 
00288 // STATISTICS: gist-any