Generated on Tue Jul 27 2010 21:59:10 for Gecode by doxygen 1.7.1

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-04-21 14:22:14 +0200 (Wed, 21 Apr 2010) $ by $Author: tack $
00011  *     $Revision: 10784 $
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 int nodeWidth = 20;
00061   const int halfNodeWidth = nodeWidth / 2;
00062   const int quarterNodeWidth = halfNodeWidth / 2;
00063   const int failedWidth = 14;
00064   const int halfFailedWidth = failedWidth / 2;
00065   const float quarterFailedWidthF = static_cast<float>(failedWidth) / 4.0;
00066   const int shadowOffset = 3;
00067   const int dSolvedOffset = nodeWidth / 6;
00068   const int dSolvedHalfWidth = (nodeWidth-2*dSolvedOffset) / 2;
00069   const int hiddenDepth = Layout::dist_y + failedWidth;
00070 
00071   DrawingCursor::DrawingCursor(Gist::VisualNode* root, BestNode* curBest0,
00072                                QPainter& painter0,
00073                                const QRect& clippingRect0, bool showCopies)
00074     : NodeCursor<VisualNode>(root), painter(painter0),
00075       clippingRect(clippingRect0), curBest(curBest0),
00076       x(0), y(0), copies(showCopies) {
00077     QPen pen = painter.pen();
00078       pen.setWidth(1);
00079       painter.setPen(pen);
00080 }
00081 
00082   bool
00083   DrawingCursor::isClipped(void) {
00084     if (clippingRect.width() == 0 && clippingRect.x() == 0
00085         && clippingRect.height() == 0 && clippingRect.y() == 0)
00086       return false;
00087     BoundingBox b = node()->getBoundingBox();
00088     return (x + b.left > clippingRect.x() + clippingRect.width() ||
00089             x + b.right < clippingRect.x() ||
00090             y > clippingRect.y() + clippingRect.height() ||
00091             y + (node()->getShape()->depth()+1) * Layout::dist_y < 
00092             clippingRect.y());
00093   }
00094 
00095   void
00096   DrawingCursor::processCurrentNode(void) {
00097     Gist::VisualNode* n = node();
00098     int parentX = x - (n->getOffset());
00099     int parentY = y - Layout::dist_y + nodeWidth;
00100     if (n->getParent() != NULL &&
00101         (n->getParent()->getStatus() == STOP ||
00102          n->getParent()->getStatus() == UNSTOP) )
00103       parentY -= (nodeWidth-failedWidth)/2;
00104 
00105     int myx = x;
00106     int myy = y;
00107 
00108     if (n->getStatus() == STOP || n->getStatus() == UNSTOP)
00109       myy += (nodeWidth-failedWidth)/2;
00110 
00111     if (n != startNode()) {
00112       if (n->isOnPath())
00113         painter.setPen(Qt::red);
00114       else
00115         painter.setPen(Qt::black);
00116       QPainterPath path;
00117       path.moveTo(myx,myy);
00118       path.lineTo(parentX,parentY);
00119       painter.drawPath(path);
00120     }
00121 
00122     // draw shadow
00123     if (n->isMarked()) {
00124       painter.setBrush(Qt::gray);
00125       painter.setPen(Qt::NoPen);
00126       if (n->isHidden()) {
00127         QPoint points[3] = {QPoint(myx+shadowOffset,myy+shadowOffset),
00128                             QPoint(myx+nodeWidth+shadowOffset,
00129                                    myy+hiddenDepth+shadowOffset),
00130                             QPoint(myx-nodeWidth+shadowOffset,
00131                                    myy+hiddenDepth+shadowOffset),
00132                            };
00133         painter.drawConvexPolygon(points, 3);
00134 
00135       } else {
00136         switch (n->getStatus()) {
00137         case Gist::SOLVED:
00138           {
00139             QPoint points[4] = {QPoint(myx+shadowOffset,myy+shadowOffset),
00140                                 QPoint(myx+halfNodeWidth+shadowOffset,
00141                                        myy+halfNodeWidth+shadowOffset),
00142                                 QPoint(myx+shadowOffset,
00143                                        myy+nodeWidth+shadowOffset),
00144                                 QPoint(myx-halfNodeWidth+shadowOffset,
00145                                        myy+halfNodeWidth+shadowOffset)
00146                                };
00147             painter.drawConvexPolygon(points, 4);
00148           }
00149           break;
00150         case Gist::FAILED:
00151           painter.drawRect(myx-halfFailedWidth+shadowOffset,
00152                            myy+shadowOffset, failedWidth, failedWidth);
00153           break;
00154         case Gist::UNSTOP:
00155         case Gist::STOP:
00156           {
00157             QPointF points[8] = {QPointF(myx+shadowOffset-quarterFailedWidthF,
00158                                          myy+shadowOffset),
00159                                  QPointF(myx+shadowOffset+quarterFailedWidthF,
00160                                          myy+shadowOffset),
00161                                  QPointF(myx+shadowOffset+halfFailedWidth,
00162                                          myy+shadowOffset
00163                                             +quarterFailedWidthF),
00164                                  QPointF(myx+shadowOffset+halfFailedWidth,
00165                                          myy+shadowOffset+halfFailedWidth+
00166                                              quarterFailedWidthF),
00167                                  QPointF(myx+shadowOffset+quarterFailedWidthF,
00168                                          myy+shadowOffset+failedWidth),
00169                                  QPointF(myx+shadowOffset-quarterFailedWidthF,
00170                                          myy+shadowOffset+failedWidth),
00171                                  QPointF(myx+shadowOffset-halfFailedWidth,
00172                                          myy+shadowOffset+halfFailedWidth+
00173                                              quarterFailedWidthF),
00174                                  QPointF(myx+shadowOffset-halfFailedWidth,
00175                                          myy+shadowOffset
00176                                             +quarterFailedWidthF),
00177                                 };
00178             painter.drawConvexPolygon(points, 8);
00179           }
00180           break;
00181         case Gist::BRANCH:
00182           painter.drawEllipse(myx-halfNodeWidth+shadowOffset,
00183                               myy+shadowOffset, nodeWidth, nodeWidth);
00184           break;
00185         case Gist::UNDETERMINED:
00186           painter.drawEllipse(myx-halfNodeWidth+shadowOffset,
00187                               myy+shadowOffset, nodeWidth, nodeWidth);
00188           break;
00189         }
00190       }
00191     }
00192 
00193     painter.setPen(Qt::SolidLine);
00194     if (n->isHidden()) {
00195       if (n->hasOpenChildren()) {
00196         QLinearGradient gradient(myx-nodeWidth,myy,myx+nodeWidth*1.3,myy+hiddenDepth*1.3);
00197         if (n->hasSolvedChildren()) {
00198           gradient.setColorAt(0, white);
00199           gradient.setColorAt(1, green);
00200         } else if (n->hasFailedChildren()) {
00201           gradient.setColorAt(0, white);
00202           gradient.setColorAt(1, red);          
00203         } else {
00204           gradient.setColorAt(0, white);
00205           gradient.setColorAt(1, QColor(0,0,0));
00206         }
00207         painter.setBrush(gradient);
00208       } else {
00209         if (n->hasSolvedChildren())
00210           painter.setBrush(QBrush(green));
00211         else
00212           painter.setBrush(QBrush(red));
00213       }
00214       
00215       QPoint points[3] = {QPoint(myx,myy),
00216                           QPoint(myx+nodeWidth,myy+hiddenDepth),
00217                           QPoint(myx-nodeWidth,myy+hiddenDepth),
00218                          };
00219       painter.drawConvexPolygon(points, 3);
00220     } else {
00221       switch (n->getStatus()) {
00222       case Gist::SOLVED:
00223         {
00224           if (n->isCurrentBest(curBest)) {
00225             painter.setBrush(QBrush(orange));
00226           } else {
00227             painter.setBrush(QBrush(green));
00228           }
00229           QPoint points[4] = {QPoint(myx,myy),
00230                               QPoint(myx+halfNodeWidth,myy+halfNodeWidth),
00231                               QPoint(myx,myy+nodeWidth),
00232                               QPoint(myx-halfNodeWidth,myy+halfNodeWidth)
00233                              };
00234           painter.drawConvexPolygon(points, 4);
00235         }
00236         break;
00237       case Gist::FAILED:
00238         painter.setBrush(QBrush(red));
00239         painter.drawRect(myx-halfFailedWidth, myy, failedWidth, failedWidth);
00240         break;
00241       case Gist::UNSTOP:
00242       case Gist::STOP:
00243         {
00244           painter.setBrush(n->getStatus() == STOP ? 
00245                            QBrush(red) : QBrush(green));
00246           QPointF points[8] = {QPointF(myx-quarterFailedWidthF,myy),
00247                                QPointF(myx+quarterFailedWidthF,myy),
00248                                QPointF(myx+halfFailedWidth,
00249                                        myy+quarterFailedWidthF),
00250                                QPointF(myx+halfFailedWidth,
00251                                        myy+halfFailedWidth+
00252                                            quarterFailedWidthF),
00253                                QPointF(myx+quarterFailedWidthF,
00254                                        myy+failedWidth),
00255                                QPointF(myx-quarterFailedWidthF,
00256                                        myy+failedWidth),
00257                                QPointF(myx-halfFailedWidth,
00258                                        myy+halfFailedWidth+
00259                                            quarterFailedWidthF),
00260                                QPointF(myx-halfFailedWidth,
00261                                        myy+quarterFailedWidthF),
00262                               };
00263           painter.drawConvexPolygon(points, 8);
00264         }
00265         break;
00266       case Gist::BRANCH:
00267         painter.setBrush(n->childrenLayoutIsDone() ? QBrush(blue) : 
00268                                                      QBrush(white));
00269         painter.drawEllipse(myx-halfNodeWidth, myy, nodeWidth, nodeWidth);
00270         break;
00271       case Gist::UNDETERMINED:
00272         painter.setBrush(Qt::white);
00273         painter.drawEllipse(myx-halfNodeWidth, myy, nodeWidth, nodeWidth);
00274         break;
00275       }
00276         
00277     }
00278 
00279     if (copies && n->hasCopy()) {
00280      painter.setBrush(Qt::darkRed);
00281      painter.drawEllipse(myx, myy, 10, 10);
00282     }
00283 
00284     if (copies && n->hasWorkingSpace()) {
00285      painter.setBrush(Qt::darkYellow);
00286      painter.drawEllipse(myx, myy + 10, 10, 10);
00287     }
00288 
00289     if (n->isBookmarked()) {
00290      painter.setBrush(Qt::black);
00291      painter.drawEllipse(myx-10, myy, 10, 10);
00292     }
00293 
00294   }
00295 
00296 }}
00297 
00298 // STATISTICS: gist-any