Generated on Mon Nov 30 23:53:19 2009 for Gecode by doxygen 1.6.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: 2009-05-13 00:53:54 +0200 (Wed, 13 May 2009) $ by $Author: tack $
00011  *     $Revision: 9076 $
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 int shadowOffset = 3;
00066   const int dSolvedOffset = nodeWidth / 6;
00067   const int dSolvedHalfWidth = (nodeWidth-2*dSolvedOffset) / 2;
00068   const int hiddenDepth = Layout::dist_y + failedWidth;
00069 
00070   DrawingCursor::DrawingCursor(Gist::VisualNode* root, BestNode* curBest0,
00071                                QPainter& painter0,
00072                                const QRect& clippingRect0, bool showCopies)
00073     : NodeCursor<VisualNode>(root), painter(painter0),
00074       clippingRect(clippingRect0), curBest(curBest0),
00075       x(0), y(0), copies(showCopies) {
00076     QPen pen = painter.pen();
00077       pen.setWidth(1);
00078       painter.setPen(pen);
00079 }
00080 
00081   bool
00082   DrawingCursor::isClipped(void) {
00083     if (clippingRect.width() == 0 && clippingRect.x() == 0
00084         && clippingRect.height() == 0 && clippingRect.y() == 0)
00085       return false;
00086     BoundingBox b = node()->getBoundingBox();
00087     return (x + b.left > clippingRect.x() + clippingRect.width() ||
00088             x + b.right < clippingRect.x() ||
00089             y > clippingRect.y() + clippingRect.height() ||
00090             y + (node()->getShape()->depth()+1) * Layout::dist_y < 
00091             clippingRect.y());
00092   }
00093 
00094   void
00095   DrawingCursor::processCurrentNode(void) {
00096     Gist::VisualNode* n = node();
00097     int parentX = x - (n->getOffset());
00098     int parentY = y - Layout::dist_y + nodeWidth;
00099 
00100     int myx = x;
00101     int myy = y;
00102 
00103     if (n != startNode()) {
00104       if (n->isOnPath())
00105         painter.setPen(Qt::red);
00106       else
00107         painter.setPen(Qt::black);
00108       QPainterPath path;
00109       path.moveTo(myx,myy);
00110       path.lineTo(parentX,parentY);
00111       painter.drawPath(path);
00112     }
00113 
00114     // draw shadow
00115     if (n->isMarked()) {
00116       painter.setBrush(Qt::gray);
00117       painter.setPen(Qt::NoPen);
00118       if (n->isHidden()) {
00119         QPoint points[3] = {QPoint(myx+shadowOffset,myy+shadowOffset),
00120                             QPoint(myx+nodeWidth+shadowOffset,
00121                                    myy+hiddenDepth+shadowOffset),
00122                             QPoint(myx-nodeWidth+shadowOffset,
00123                                    myy+hiddenDepth+shadowOffset),
00124                            };
00125         painter.drawConvexPolygon(points, 3);
00126 
00127       } else {
00128         switch (n->getStatus()) {
00129         case Gist::STEP:
00130         case Gist::SPECIAL:
00131                 painter.drawEllipse(myx-quarterNodeWidth+shadowOffset,
00132                                     myy+shadowOffset, halfNodeWidth,
00133                                     nodeWidth);
00134                 break;
00135         case Gist::SOLVED:
00136           {
00137             QPoint points[4] = {QPoint(myx+shadowOffset,myy+shadowOffset),
00138                                 QPoint(myx+halfNodeWidth+shadowOffset,
00139                                        myy+halfNodeWidth+shadowOffset),
00140                                 QPoint(myx+shadowOffset,
00141                                        myy+nodeWidth+shadowOffset),
00142                                 QPoint(myx-halfNodeWidth+shadowOffset,
00143                                        myy+halfNodeWidth+shadowOffset)
00144                                };
00145             painter.drawConvexPolygon(points, 4);
00146           }
00147           break;
00148         case Gist::FAILED:
00149           painter.drawRect(myx-halfFailedWidth+shadowOffset,
00150                            myy+shadowOffset, failedWidth, failedWidth);
00151           break;
00152         case Gist::BRANCH:
00153           painter.drawEllipse(myx-halfNodeWidth+shadowOffset,
00154                               myy+shadowOffset, nodeWidth, nodeWidth);
00155           break;
00156         case Gist::UNDETERMINED:
00157           painter.drawEllipse(myx-halfNodeWidth+shadowOffset,
00158                               myy+shadowOffset, nodeWidth, nodeWidth);
00159           break;
00160         }
00161       }
00162     }
00163 
00164     painter.setPen(Qt::SolidLine);
00165     if (n->isHidden()) {
00166       if (n->hasOpenChildren()) {
00167         QLinearGradient gradient(myx-nodeWidth,myy,myx+nodeWidth*1.3,myy+hiddenDepth*1.3);
00168         if (n->hasSolvedChildren()) {
00169           gradient.setColorAt(0, white);
00170           gradient.setColorAt(1, green);
00171         } else if (n->hasFailedChildren()) {
00172           gradient.setColorAt(0, white);
00173           gradient.setColorAt(1, red);          
00174         } else {
00175           gradient.setColorAt(0, white);
00176           gradient.setColorAt(1, QColor(0,0,0));
00177         }
00178         painter.setBrush(gradient);
00179       } else {
00180         if (n->hasSolvedChildren())
00181           painter.setBrush(QBrush(green));
00182         else
00183           painter.setBrush(QBrush(red));
00184       }
00185       
00186       QPoint points[3] = {QPoint(myx,myy),
00187                           QPoint(myx+nodeWidth,myy+hiddenDepth),
00188                           QPoint(myx-nodeWidth,myy+hiddenDepth),
00189                          };
00190       painter.drawConvexPolygon(points, 3);
00191     } else {
00192       switch (n->getStatus()) {
00193       case Gist::STEP:
00194       case Gist::SPECIAL:
00195         painter.setBrush(Qt::yellow);
00196         painter.drawEllipse(myx-quarterNodeWidth, myy+halfNodeWidth,
00197                            halfNodeWidth, halfNodeWidth);
00198         if (n->isOnPath())
00199           painter.setPen(Qt::red);
00200         else
00201           painter.setPen(Qt::black);
00202         painter.drawLine(myx, myy, myx, myy+halfNodeWidth);
00203         break;
00204       case Gist::SOLVED:
00205         {
00206           if (n->isCurrentBest(curBest)) {
00207             painter.setBrush(QBrush(orange));
00208           } else {
00209             painter.setBrush(QBrush(green));
00210           }
00211           QPoint points[4] = {QPoint(myx,myy),
00212                               QPoint(myx+halfNodeWidth,myy+halfNodeWidth),
00213                               QPoint(myx,myy+nodeWidth),
00214                               QPoint(myx-halfNodeWidth,myy+halfNodeWidth)
00215                              };
00216           painter.drawConvexPolygon(points, 4);
00217         }
00218         break;
00219       case Gist::FAILED:
00220         painter.setBrush(QBrush(red));
00221         painter.drawRect(myx-halfFailedWidth, myy, failedWidth, failedWidth);
00222         break;
00223       case Gist::BRANCH:
00224         painter.setBrush(QBrush(blue));
00225         painter.drawEllipse(myx-halfNodeWidth, myy, nodeWidth, nodeWidth);
00226         break;
00227       case Gist::UNDETERMINED:
00228         painter.setBrush(Qt::white);
00229         painter.drawEllipse(myx-halfNodeWidth, myy, nodeWidth, nodeWidth);
00230         break;
00231       }
00232         
00233     }
00234 
00235     if (copies && n->hasCopy()) {
00236      painter.setBrush(Qt::darkRed);
00237      painter.drawEllipse(myx, myy, 10, 10);
00238     }
00239 
00240     if (copies && n->hasWorkingSpace()) {
00241      painter.setBrush(Qt::darkYellow);
00242      painter.drawEllipse(myx, myy + 10, 10, 10);
00243     }
00244 
00245   }
00246 
00247 }}
00248 
00249 // STATISTICS: gist-any