Generated on Fri Jan 10 2020 11:38:25 for Gecode by doxygen 1.8.16
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  * This file is part of Gecode, the generic constraint
10  * development environment:
11  * http://www.gecode.org
12  *
13  * Permission is hereby granted, free of charge, to any person obtaining
14  * a copy of this software and associated documentation files (the
15  * "Software"), to deal in the Software without restriction, including
16  * without limitation the rights to use, copy, modify, merge, publish,
17  * distribute, sublicense, and/or sell copies of the Software, and to
18  * permit persons to whom the Software is furnished to do so, subject to
19  * the following conditions:
20  *
21  * The above copyright notice and this permission notice shall be
22  * included in all copies or substantial portions of the Software.
23  *
24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31  *
32  */
33 
35 
36 namespace Gecode { namespace Gist {
37 
39  const QColor DrawingCursor::red(218, 37, 29);
41  const QColor DrawingCursor::green(11, 118, 70);
43  const QColor DrawingCursor::blue(0, 92, 161);
45  const QColor DrawingCursor::orange(235, 137, 27);
47  const QColor DrawingCursor::white(255,255,255);
48 
50  const QColor DrawingCursor::lightRed(218, 37, 29, 120);
52  const QColor DrawingCursor::lightGreen(11, 118, 70, 120);
54  const QColor DrawingCursor::lightBlue(0, 92, 161, 120);
55 
56  const double nodeWidth = 20.0;
57  const double halfNodeWidth = nodeWidth / 2.0;
58  const double failedWidth = 14.0;
59  const double halfFailedWidth = failedWidth / 2.0;
60  const double quarterFailedWidthF = failedWidth / 4.0;
61  const double shadowOffset = 3.0;
62  const double hiddenDepth =
63  static_cast<double>(Layout::dist_y) + failedWidth;
64 
66  const VisualNode::NodeAllocator& na,
67  BestNode* curBest0,
68  QPainter& painter0,
69  const QRect& clippingRect0, bool showCopies)
70  : NodeCursor<VisualNode>(root,na), painter(painter0),
71  clippingRect(clippingRect0), curBest(curBest0),
72  x(0.0), y(0.0), copies(showCopies) {
73  QPen pen = painter.pen();
74  pen.setWidth(1);
75  painter.setPen(pen);
76  }
77 
78  void
80  Gist::VisualNode* n = node();
81  double parentX = x - static_cast<double>(n->getOffset());
82  double parentY = y - static_cast<double>(Layout::dist_y) + nodeWidth;
83  if (!n->isRoot() &&
84  (n->getParent(na)->getStatus() == STOP ||
85  n->getParent(na)->getStatus() == UNSTOP) )
86  parentY -= (nodeWidth-failedWidth)/2;
87 
88  double myx = x;
89  double myy = y;
90 
91  if (n->getStatus() == STOP || n->getStatus() == UNSTOP)
92  myy += (nodeWidth-failedWidth)/2;
93 
94  if (n != startNode()) {
95  if (n->isOnPath())
96  painter.setPen(Qt::red);
97  else
98  painter.setPen(Qt::black);
99  // Here we use drawPath instead of drawLine in order to
100  // workaround a strange redraw artefact on Windows
101  QPainterPath path;
102  path.moveTo(myx,myy);
103  path.lineTo(parentX,parentY);
104  painter.drawPath(path);
105 
106  QFontMetrics fm = painter.fontMetrics();
107  QString label = na.getLabel(n);
108  int alt = n->getAlternative(na);
109  int n_alt = n->getParent(na)->getNumberOfChildren();
110  int tw = fm.width(label);
111  int lx;
112  if (alt==0 && n_alt > 1) {
113  lx = myx-tw-4;
114  } else if (alt==n_alt-1 && n_alt > 1) {
115  lx = myx+4;
116  } else {
117  lx = myx-tw/2;
118  }
119  painter.drawText(QPointF(lx,myy-2),label);
120  }
121 
122  // draw shadow
123  if (n->isMarked()) {
124  painter.setBrush(Qt::gray);
125  painter.setPen(Qt::NoPen);
126  if (n->isHidden()) {
127  QPointF points[3] = {QPointF(myx+shadowOffset,myy+shadowOffset),
128  QPointF(myx+nodeWidth+shadowOffset,
130  QPointF(myx-nodeWidth+shadowOffset,
132  };
133  painter.drawConvexPolygon(points, 3);
134 
135  } else {
136  switch (n->getStatus()) {
137  case Gist::SOLVED:
138  {
139  QPointF points[4] = {QPointF(myx+shadowOffset,myy+shadowOffset),
140  QPointF(myx+halfNodeWidth+shadowOffset,
142  QPointF(myx+shadowOffset,
143  myy+nodeWidth+shadowOffset),
144  QPointF(myx-halfNodeWidth+shadowOffset,
146  };
147  painter.drawConvexPolygon(points, 4);
148  }
149  break;
150  case Gist::FAILED:
151  painter.drawRect(myx-halfFailedWidth+shadowOffset,
153  break;
154  case Gist::UNSTOP:
155  case Gist::STOP:
156  {
157  QPointF points[8] = {QPointF(myx+shadowOffset-quarterFailedWidthF,
158  myy+shadowOffset),
159  QPointF(myx+shadowOffset+quarterFailedWidthF,
160  myy+shadowOffset),
161  QPointF(myx+shadowOffset+halfFailedWidth,
162  myy+shadowOffset
164  QPointF(myx+shadowOffset+halfFailedWidth,
167  QPointF(myx+shadowOffset+quarterFailedWidthF,
169  QPointF(myx+shadowOffset-quarterFailedWidthF,
171  QPointF(myx+shadowOffset-halfFailedWidth,
174  QPointF(myx+shadowOffset-halfFailedWidth,
175  myy+shadowOffset
177  };
178  painter.drawConvexPolygon(points, 8);
179  }
180  break;
181  case Gist::BRANCH:
182  painter.drawEllipse(myx-halfNodeWidth+shadowOffset,
184  break;
185  case Gist::UNDETERMINED:
186  painter.drawEllipse(myx-halfNodeWidth+shadowOffset,
188  break;
189  }
190  }
191  }
192 
193  painter.setPen(Qt::SolidLine);
194  if (n->isHidden()) {
195  if (n->hasOpenChildren()) {
196  QLinearGradient gradient(myx-nodeWidth,myy,
197  myx+nodeWidth*1.3,myy+hiddenDepth*1.3);
198  if (n->hasSolvedChildren()) {
199  gradient.setColorAt(0, white);
200  gradient.setColorAt(1, green);
201  } else if (n->hasFailedChildren()) {
202  gradient.setColorAt(0, white);
203  gradient.setColorAt(1, red);
204  } else {
205  gradient.setColorAt(0, white);
206  gradient.setColorAt(1, QColor(0,0,0));
207  }
208  painter.setBrush(gradient);
209  } else {
210  if (n->hasSolvedChildren())
211  painter.setBrush(QBrush(green));
212  else
213  painter.setBrush(QBrush(red));
214  }
215 
216  QPointF points[3] = {QPointF(myx,myy),
217  QPointF(myx+nodeWidth,myy+hiddenDepth),
218  QPointF(myx-nodeWidth,myy+hiddenDepth),
219  };
220  painter.drawConvexPolygon(points, 3);
221  } else {
222  switch (n->getStatus()) {
223  case Gist::SOLVED:
224  {
225  if (n->isCurrentBest(curBest)) {
226  painter.setBrush(QBrush(orange));
227  } else {
228  painter.setBrush(QBrush(green));
229  }
230  QPointF points[4] = {QPointF(myx,myy),
231  QPointF(myx+halfNodeWidth,myy+halfNodeWidth),
232  QPointF(myx,myy+nodeWidth),
233  QPointF(myx-halfNodeWidth,myy+halfNodeWidth)
234  };
235  painter.drawConvexPolygon(points, 4);
236  }
237  break;
238  case Gist::FAILED:
239  painter.setBrush(QBrush(red));
240  painter.drawRect(myx-halfFailedWidth, myy, failedWidth, failedWidth);
241  break;
242  case Gist::UNSTOP:
243  case Gist::STOP:
244  {
245  painter.setBrush(n->getStatus() == STOP ?
246  QBrush(red) : QBrush(green));
247  QPointF points[8] = {QPointF(myx-quarterFailedWidthF,myy),
248  QPointF(myx+quarterFailedWidthF,myy),
249  QPointF(myx+halfFailedWidth,
250  myy+quarterFailedWidthF),
251  QPointF(myx+halfFailedWidth,
252  myy+halfFailedWidth+
254  QPointF(myx+quarterFailedWidthF,
255  myy+failedWidth),
256  QPointF(myx-quarterFailedWidthF,
257  myy+failedWidth),
258  QPointF(myx-halfFailedWidth,
259  myy+halfFailedWidth+
261  QPointF(myx-halfFailedWidth,
262  myy+quarterFailedWidthF),
263  };
264  painter.drawConvexPolygon(points, 8);
265  }
266  break;
267  case Gist::BRANCH:
268  painter.setBrush(n->childrenLayoutIsDone() ? QBrush(blue) :
269  QBrush(white));
270  painter.drawEllipse(myx-halfNodeWidth, myy, nodeWidth, nodeWidth);
271  break;
272  case Gist::UNDETERMINED:
273  painter.setBrush(Qt::white);
274  painter.drawEllipse(myx-halfNodeWidth, myy, nodeWidth, nodeWidth);
275  break;
276  }
277  }
278 
279  if (copies && (n->hasCopy() && !n->hasWorkingSpace())) {
280  painter.setBrush(Qt::darkRed);
281  painter.drawEllipse(myx, myy, 10.0, 10.0);
282  }
283 
284  if (copies && n->hasWorkingSpace()) {
285  painter.setBrush(Qt::darkYellow);
286  painter.drawEllipse(myx, myy + 10.0, 10.0, 10.0);
287  }
288 
289  if (n->isBookmarked()) {
290  painter.setBrush(Qt::black);
291  painter.drawEllipse(myx-10-0, myy, 10.0, 10.0);
292  }
293 
294  }
295 
296 }}
297 
298 // STATISTICS: gist-any
Node that has not been explored yet.
Definition: spacenode.hh:48
const double quarterFailedWidthF
Post propagator for SetVar x
Definition: set.hh:767
Post propagator for SetVar SetOpType SetVar y
Definition: set.hh:767
A cursor that can be run over a tree.
Definition: nodecursor.hh:43
Gecode Interactive Search Tool
Definition: qtgist.hh:81
Node representing stop point.
Definition: spacenode.hh:49
Node class that supports visual layout
Definition: visualnode.hh:125
static const QColor orange
The color for the best solution.
void processCurrentNode(void)
Draw the node.
const double failedWidth
const double hiddenDepth
static const QColor red
The color for failed nodes.
const double halfFailedWidth
const double nodeWidth
Gecode toplevel namespace
const VisualNode ::NodeAllocator & na
The node allocator.
Definition: nodecursor.hh:53
static const int dist_y
Definition: visualnode.hh:46
const double halfNodeWidth
Node allocator.
Definition: node.hh:48
static const QColor lightRed
The color for expanded failed nodes.
Static reference to the currently best space.
Definition: spacenode.hh:80
static const QColor lightBlue
The color for expanded choice nodes.
Node representing a branch.
Definition: spacenode.hh:47
const double shadowOffset
VisualNode * startNode(void)
Return start node.
Definition: nodecursor.hpp:58
static const QColor blue
The color for choice nodes.
void path(Home home, int offset, const IntVarArgs &x, IntVar s, IntVar e, IntPropLevel ipl)
Post propagator such that x forms a Hamiltonian path.
Definition: circuit.cpp:124
DrawingCursor(VisualNode *root, const VisualNode::NodeAllocator &na, BestNode *curBest0, QPainter &painter0, const QRect &clippingRect0, bool showCopies)
Constructor.
Node representing ignored stop point.
Definition: spacenode.hh:50
int n
Number of negative literals for node type.
Definition: bool-expr.cpp:234
Node representing failure.
Definition: spacenode.hh:46
static const QColor lightGreen
The color for expanded solved nodes.
static const QColor white
White color.
Node representing a solution.
Definition: spacenode.hh:45
static const QColor green
The color for solved nodes.
VisualNode * node(void)
Return current node.
Definition: nodecursor.hpp:46