Generated on Mon Aug 27 2012 17:15:35 for Gecode by doxygen 1.8.1.2
drawingcursor.cpp
Go to the documentation of this file.
1 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2 /*
3  * Main authors:
4  * Guido Tack <tack@gecode.org>
5  *
6  * Copyright:
7  * Guido Tack, 2006
8  *
9  * Last modified:
10  * $Date: 2010-08-12 17:48:30 +1000 (Thu, 12 Aug 2010) $ by $Author: tack $
11  * $Revision: 11345 $
12  *
13  * This file is part of Gecode, the generic constraint
14  * development environment:
15  * http://www.gecode.org
16  *
17  * Permission is hereby granted, free of charge, to any person obtaining
18  * a copy of this software and associated documentation files (the
19  * "Software"), to deal in the Software without restriction, including
20  * without limitation the rights to use, copy, modify, merge, publish,
21  * distribute, sublicense, and/or sell copies of the Software, and to
22  * permit persons to whom the Software is furnished to do so, subject to
23  * the following conditions:
24  *
25  * The above copyright notice and this permission notice shall be
26  * included in all copies or substantial portions of the Software.
27  *
28  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
32  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
33  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
34  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35  *
36  */
37 
39 
40 namespace Gecode { namespace Gist {
41 
43  const QColor DrawingCursor::red(218, 37, 29);
45  const QColor DrawingCursor::green(11, 118, 70);
47  const QColor DrawingCursor::blue(0, 92, 161);
49  const QColor DrawingCursor::orange(235, 137, 27);
51  const QColor DrawingCursor::white(255,255,255);
52 
54  const QColor DrawingCursor::lightRed(218, 37, 29, 120);
56  const QColor DrawingCursor::lightGreen(11, 118, 70, 120);
58  const QColor DrawingCursor::lightBlue(0, 92, 161, 120);
59 
60  const double nodeWidth = 20.0;
61  const double halfNodeWidth = nodeWidth / 2.0;
62  const double quarterNodeWidth = halfNodeWidth / 2.0;
63  const double failedWidth = 14.0;
64  const double halfFailedWidth = failedWidth / 2.0;
65  const double quarterFailedWidthF = failedWidth / 4.0;
66  const double shadowOffset = 3.0;
67  const double hiddenDepth =
68  static_cast<double>(Layout::dist_y) + failedWidth;
69 
71  const VisualNode::NodeAllocator& na,
72  BestNode* curBest0,
73  QPainter& painter0,
74  const QRect& clippingRect0, bool showCopies)
75  : NodeCursor<VisualNode>(root,na), painter(painter0),
76  clippingRect(clippingRect0), curBest(curBest0),
77  x(0.0), y(0.0), copies(showCopies) {
78  QPen pen = painter.pen();
79  pen.setWidth(1);
80  painter.setPen(pen);
81  }
82 
83  void
85  Gist::VisualNode* n = node();
86  double parentX = x - static_cast<double>(n->getOffset());
87  double parentY = y - static_cast<double>(Layout::dist_y) + nodeWidth;
88  if (!n->isRoot() &&
89  (n->getParent(na)->getStatus() == STOP ||
90  n->getParent(na)->getStatus() == UNSTOP) )
91  parentY -= (nodeWidth-failedWidth)/2;
92 
93  double myx = x;
94  double myy = y;
95 
96  if (n->getStatus() == STOP || n->getStatus() == UNSTOP)
97  myy += (nodeWidth-failedWidth)/2;
98 
99  if (n != startNode()) {
100  if (n->isOnPath())
101  painter.setPen(Qt::red);
102  else
103  painter.setPen(Qt::black);
104  // Here we use drawPath instead of drawLine in order to
105  // workaround a strange redraw artefact on Windows
106  QPainterPath path;
107  path.moveTo(myx,myy);
108  path.lineTo(parentX,parentY);
109  painter.drawPath(path);
110  }
111 
112  // draw shadow
113  if (n->isMarked()) {
114  painter.setBrush(Qt::gray);
115  painter.setPen(Qt::NoPen);
116  if (n->isHidden()) {
117  QPointF points[3] = {QPointF(myx+shadowOffset,myy+shadowOffset),
118  QPointF(myx+nodeWidth+shadowOffset,
120  QPointF(myx-nodeWidth+shadowOffset,
122  };
123  painter.drawConvexPolygon(points, 3);
124 
125  } else {
126  switch (n->getStatus()) {
127  case Gist::SOLVED:
128  {
129  QPointF points[4] = {QPointF(myx+shadowOffset,myy+shadowOffset),
130  QPointF(myx+halfNodeWidth+shadowOffset,
132  QPointF(myx+shadowOffset,
133  myy+nodeWidth+shadowOffset),
134  QPointF(myx-halfNodeWidth+shadowOffset,
136  };
137  painter.drawConvexPolygon(points, 4);
138  }
139  break;
140  case Gist::FAILED:
141  painter.drawRect(myx-halfFailedWidth+shadowOffset,
143  break;
144  case Gist::UNSTOP:
145  case Gist::STOP:
146  {
147  QPointF points[8] = {QPointF(myx+shadowOffset-quarterFailedWidthF,
148  myy+shadowOffset),
149  QPointF(myx+shadowOffset+quarterFailedWidthF,
150  myy+shadowOffset),
151  QPointF(myx+shadowOffset+halfFailedWidth,
152  myy+shadowOffset
154  QPointF(myx+shadowOffset+halfFailedWidth,
157  QPointF(myx+shadowOffset+quarterFailedWidthF,
159  QPointF(myx+shadowOffset-quarterFailedWidthF,
161  QPointF(myx+shadowOffset-halfFailedWidth,
164  QPointF(myx+shadowOffset-halfFailedWidth,
165  myy+shadowOffset
167  };
168  painter.drawConvexPolygon(points, 8);
169  }
170  break;
171  case Gist::BRANCH:
172  painter.drawEllipse(myx-halfNodeWidth+shadowOffset,
174  break;
175  case Gist::UNDETERMINED:
176  painter.drawEllipse(myx-halfNodeWidth+shadowOffset,
178  break;
179  }
180  }
181  }
182 
183  painter.setPen(Qt::SolidLine);
184  if (n->isHidden()) {
185  if (n->hasOpenChildren()) {
186  QLinearGradient gradient(myx-nodeWidth,myy,
187  myx+nodeWidth*1.3,myy+hiddenDepth*1.3);
188  if (n->hasSolvedChildren()) {
189  gradient.setColorAt(0, white);
190  gradient.setColorAt(1, green);
191  } else if (n->hasFailedChildren()) {
192  gradient.setColorAt(0, white);
193  gradient.setColorAt(1, red);
194  } else {
195  gradient.setColorAt(0, white);
196  gradient.setColorAt(1, QColor(0,0,0));
197  }
198  painter.setBrush(gradient);
199  } else {
200  if (n->hasSolvedChildren())
201  painter.setBrush(QBrush(green));
202  else
203  painter.setBrush(QBrush(red));
204  }
205 
206  QPointF points[3] = {QPointF(myx,myy),
207  QPointF(myx+nodeWidth,myy+hiddenDepth),
208  QPointF(myx-nodeWidth,myy+hiddenDepth),
209  };
210  painter.drawConvexPolygon(points, 3);
211  } else {
212  switch (n->getStatus()) {
213  case Gist::SOLVED:
214  {
215  if (n->isCurrentBest(curBest)) {
216  painter.setBrush(QBrush(orange));
217  } else {
218  painter.setBrush(QBrush(green));
219  }
220  QPointF points[4] = {QPointF(myx,myy),
221  QPointF(myx+halfNodeWidth,myy+halfNodeWidth),
222  QPointF(myx,myy+nodeWidth),
223  QPointF(myx-halfNodeWidth,myy+halfNodeWidth)
224  };
225  painter.drawConvexPolygon(points, 4);
226  }
227  break;
228  case Gist::FAILED:
229  painter.setBrush(QBrush(red));
230  painter.drawRect(myx-halfFailedWidth, myy, failedWidth, failedWidth);
231  break;
232  case Gist::UNSTOP:
233  case Gist::STOP:
234  {
235  painter.setBrush(n->getStatus() == STOP ?
236  QBrush(red) : QBrush(green));
237  QPointF points[8] = {QPointF(myx-quarterFailedWidthF,myy),
238  QPointF(myx+quarterFailedWidthF,myy),
239  QPointF(myx+halfFailedWidth,
240  myy+quarterFailedWidthF),
241  QPointF(myx+halfFailedWidth,
242  myy+halfFailedWidth+
244  QPointF(myx+quarterFailedWidthF,
245  myy+failedWidth),
246  QPointF(myx-quarterFailedWidthF,
247  myy+failedWidth),
248  QPointF(myx-halfFailedWidth,
249  myy+halfFailedWidth+
251  QPointF(myx-halfFailedWidth,
252  myy+quarterFailedWidthF),
253  };
254  painter.drawConvexPolygon(points, 8);
255  }
256  break;
257  case Gist::BRANCH:
258  painter.setBrush(n->childrenLayoutIsDone() ? QBrush(blue) :
259  QBrush(white));
260  painter.drawEllipse(myx-halfNodeWidth, myy, nodeWidth, nodeWidth);
261  break;
262  case Gist::UNDETERMINED:
263  painter.setBrush(Qt::white);
264  painter.drawEllipse(myx-halfNodeWidth, myy, nodeWidth, nodeWidth);
265  break;
266  }
267  }
268 
269  if (copies && (n->hasCopy() && !n->hasWorkingSpace())) {
270  painter.setBrush(Qt::darkRed);
271  painter.drawEllipse(myx, myy, 10.0, 10.0);
272  }
273 
274  if (copies && n->hasWorkingSpace()) {
275  painter.setBrush(Qt::darkYellow);
276  painter.drawEllipse(myx, myy + 10.0, 10.0, 10.0);
277  }
278 
279  if (n->isBookmarked()) {
280  painter.setBrush(Qt::black);
281  painter.drawEllipse(myx-10-0, myy, 10.0, 10.0);
282  }
283 
284  }
285 
286 }}
287 
288 // STATISTICS: gist-any