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 #include <gecode/gist/drawingcursor.hh>
00035
00036 namespace Gecode { namespace Gist {
00037
00039 const QColor DrawingCursor::red(218, 37, 29);
00041 const QColor DrawingCursor::green(11, 118, 70);
00043 const QColor DrawingCursor::blue(0, 92, 161);
00045 const QColor DrawingCursor::orange(235, 137, 27);
00047 const QColor DrawingCursor::white(255,255,255);
00048
00050 const QColor DrawingCursor::lightRed(218, 37, 29, 120);
00052 const QColor DrawingCursor::lightGreen(11, 118, 70, 120);
00054 const QColor DrawingCursor::lightBlue(0, 92, 161, 120);
00055
00056 const double nodeWidth = 20.0;
00057 const double halfNodeWidth = nodeWidth / 2.0;
00058 const double failedWidth = 14.0;
00059 const double halfFailedWidth = failedWidth / 2.0;
00060 const double quarterFailedWidthF = failedWidth / 4.0;
00061 const double shadowOffset = 3.0;
00062 const double hiddenDepth =
00063 static_cast<double>(Layout::dist_y) + failedWidth;
00064
00065 DrawingCursor::DrawingCursor(VisualNode* root,
00066 const VisualNode::NodeAllocator& na,
00067 BestNode* curBest0,
00068 QPainter& painter0,
00069 const QRect& clippingRect0, bool showCopies)
00070 : NodeCursor<VisualNode>(root,na), painter(painter0),
00071 clippingRect(clippingRect0), curBest(curBest0),
00072 x(0.0), y(0.0), copies(showCopies) {
00073 QPen pen = painter.pen();
00074 pen.setWidth(1);
00075 painter.setPen(pen);
00076 }
00077
00078 void
00079 DrawingCursor::processCurrentNode(void) {
00080 Gist::VisualNode* n = node();
00081 double parentX = x - static_cast<double>(n->getOffset());
00082 double parentY = y - static_cast<double>(Layout::dist_y) + nodeWidth;
00083 if (!n->isRoot() &&
00084 (n->getParent(na)->getStatus() == STOP ||
00085 n->getParent(na)->getStatus() == UNSTOP) )
00086 parentY -= (nodeWidth-failedWidth)/2;
00087
00088 double myx = x;
00089 double myy = y;
00090
00091 if (n->getStatus() == STOP || n->getStatus() == UNSTOP)
00092 myy += (nodeWidth-failedWidth)/2;
00093
00094 if (n != startNode()) {
00095 if (n->isOnPath())
00096 painter.setPen(Qt::red);
00097 else
00098 painter.setPen(Qt::black);
00099
00100
00101 QPainterPath path;
00102 path.moveTo(myx,myy);
00103 path.lineTo(parentX,parentY);
00104 painter.drawPath(path);
00105
00106 QFontMetrics fm = painter.fontMetrics();
00107 QString label = na.getLabel(n);
00108 int alt = n->getAlternative(na);
00109 int n_alt = n->getParent(na)->getNumberOfChildren();
00110 int tw = fm.width(label);
00111 int lx;
00112 if (alt==0 && n_alt > 1) {
00113 lx = myx-tw-4;
00114 } else if (alt==n_alt-1 && n_alt > 1) {
00115 lx = myx+4;
00116 } else {
00117 lx = myx-tw/2;
00118 }
00119 painter.drawText(QPointF(lx,myy-2),label);
00120 }
00121
00122
00123 if (n->isMarked()) {
00124 painter.setBrush(Qt::gray);
00125 painter.setPen(Qt::NoPen);
00126 if (n->isHidden()) {
00127 QPointF points[3] = {QPointF(myx+shadowOffset,myy+shadowOffset),
00128 QPointF(myx+nodeWidth+shadowOffset,
00129 myy+hiddenDepth+shadowOffset),
00130 QPointF(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 QPointF points[4] = {QPointF(myx+shadowOffset,myy+shadowOffset),
00140 QPointF(myx+halfNodeWidth+shadowOffset,
00141 myy+halfNodeWidth+shadowOffset),
00142 QPointF(myx+shadowOffset,
00143 myy+nodeWidth+shadowOffset),
00144 QPointF(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,
00197 myx+nodeWidth*1.3,myy+hiddenDepth*1.3);
00198 if (n->hasSolvedChildren()) {
00199 gradient.setColorAt(0, white);
00200 gradient.setColorAt(1, green);
00201 } else if (n->hasFailedChildren()) {
00202 gradient.setColorAt(0, white);
00203 gradient.setColorAt(1, red);
00204 } else {
00205 gradient.setColorAt(0, white);
00206 gradient.setColorAt(1, QColor(0,0,0));
00207 }
00208 painter.setBrush(gradient);
00209 } else {
00210 if (n->hasSolvedChildren())
00211 painter.setBrush(QBrush(green));
00212 else
00213 painter.setBrush(QBrush(red));
00214 }
00215
00216 QPointF points[3] = {QPointF(myx,myy),
00217 QPointF(myx+nodeWidth,myy+hiddenDepth),
00218 QPointF(myx-nodeWidth,myy+hiddenDepth),
00219 };
00220 painter.drawConvexPolygon(points, 3);
00221 } else {
00222 switch (n->getStatus()) {
00223 case Gist::SOLVED:
00224 {
00225 if (n->isCurrentBest(curBest)) {
00226 painter.setBrush(QBrush(orange));
00227 } else {
00228 painter.setBrush(QBrush(green));
00229 }
00230 QPointF points[4] = {QPointF(myx,myy),
00231 QPointF(myx+halfNodeWidth,myy+halfNodeWidth),
00232 QPointF(myx,myy+nodeWidth),
00233 QPointF(myx-halfNodeWidth,myy+halfNodeWidth)
00234 };
00235 painter.drawConvexPolygon(points, 4);
00236 }
00237 break;
00238 case Gist::FAILED:
00239 painter.setBrush(QBrush(red));
00240 painter.drawRect(myx-halfFailedWidth, myy, failedWidth, failedWidth);
00241 break;
00242 case Gist::UNSTOP:
00243 case Gist::STOP:
00244 {
00245 painter.setBrush(n->getStatus() == STOP ?
00246 QBrush(red) : QBrush(green));
00247 QPointF points[8] = {QPointF(myx-quarterFailedWidthF,myy),
00248 QPointF(myx+quarterFailedWidthF,myy),
00249 QPointF(myx+halfFailedWidth,
00250 myy+quarterFailedWidthF),
00251 QPointF(myx+halfFailedWidth,
00252 myy+halfFailedWidth+
00253 quarterFailedWidthF),
00254 QPointF(myx+quarterFailedWidthF,
00255 myy+failedWidth),
00256 QPointF(myx-quarterFailedWidthF,
00257 myy+failedWidth),
00258 QPointF(myx-halfFailedWidth,
00259 myy+halfFailedWidth+
00260 quarterFailedWidthF),
00261 QPointF(myx-halfFailedWidth,
00262 myy+quarterFailedWidthF),
00263 };
00264 painter.drawConvexPolygon(points, 8);
00265 }
00266 break;
00267 case Gist::BRANCH:
00268 painter.setBrush(n->childrenLayoutIsDone() ? QBrush(blue) :
00269 QBrush(white));
00270 painter.drawEllipse(myx-halfNodeWidth, myy, nodeWidth, nodeWidth);
00271 break;
00272 case Gist::UNDETERMINED:
00273 painter.setBrush(Qt::white);
00274 painter.drawEllipse(myx-halfNodeWidth, myy, nodeWidth, nodeWidth);
00275 break;
00276 }
00277 }
00278
00279 if (copies && (n->hasCopy() && !n->hasWorkingSpace())) {
00280 painter.setBrush(Qt::darkRed);
00281 painter.drawEllipse(myx, myy, 10.0, 10.0);
00282 }
00283
00284 if (copies && n->hasWorkingSpace()) {
00285 painter.setBrush(Qt::darkYellow);
00286 painter.drawEllipse(myx, myy + 10.0, 10.0, 10.0);
00287 }
00288
00289 if (n->isBookmarked()) {
00290 painter.setBrush(Qt::black);
00291 painter.drawEllipse(myx-10-0, myy, 10.0, 10.0);
00292 }
00293
00294 }
00295
00296 }}
00297
00298