00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
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
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(QBrush(blue));
00268 painter.drawEllipse(myx-halfNodeWidth, myy, nodeWidth, nodeWidth);
00269 break;
00270 case Gist::UNDETERMINED:
00271 painter.setBrush(Qt::white);
00272 painter.drawEllipse(myx-halfNodeWidth, myy, nodeWidth, nodeWidth);
00273 break;
00274 }
00275
00276 }
00277
00278 if (copies && n->hasCopy()) {
00279 painter.setBrush(Qt::darkRed);
00280 painter.drawEllipse(myx, myy, 10, 10);
00281 }
00282
00283 if (copies && n->hasWorkingSpace()) {
00284 painter.setBrush(Qt::darkYellow);
00285 painter.drawEllipse(myx, myy + 10, 10, 10);
00286 }
00287
00288 if (n->isBookmarked()) {
00289 painter.setBrush(Qt::black);
00290 painter.drawEllipse(myx-10, myy, 10, 10);
00291 }
00292
00293 }
00294
00295 }}
00296
00297