PeriDyno 1.2.1
Loading...
Searching...
No Matches
WtNodeGraphicsObject.cpp
Go to the documentation of this file.
2
4
6
7void WtNodePainter::paint(Wt::WPainter* painter, WtNode& node, WtFlowScene const& scene)
8{
9 WtNodeGeometry const& geom = node.nodeGeometry();
10
11 WtNodeState const& state = node.nodeState();
12
13 WtNodeGraphicsObject const& graphicsObject = node.nodeGraphicsObject();
14
15 WtNodeDataModel const* model = node.nodeDataModel();
16
17 drawNodeRect(painter, geom, model, graphicsObject);
18
19 drawHotKeys(painter, geom, model, graphicsObject);
20
21 drawConnectionPoints(painter, geom, state, model, scene, graphicsObject);
22
23 drawModelName(painter, geom, state, model);
24
25 drawEntryLabels(painter, geom, state, model);
26
27 drawResizeRect(painter, geom, model);
28
29 drawValidationRect(painter, geom, model, graphicsObject);
30}
31
33 Wt::WPainter* painter,
34 WtNodeGeometry const& geom,
35 WtNodeDataModel const* model,
36 WtNodeGraphicsObject const& graphicsObject)
37{
38 WtNodeStyle const& nodeStyle = model->nodeStyle();
39
40 auto color = nodeStyle.NormalBoundaryColor;
41 if (graphicsObject.selectType() == 1)
42 {
43 color = nodeStyle.SelectedBoundaryColor;
44 }
45 if (graphicsObject.selectType() == 2)
46 {
47 color = nodeStyle.SelectedDragColor;
48 }
49
50 if (geom.hovered())
51 {
52 Wt::WPen p(color);
53 p.setWidth(nodeStyle.HoveredPenWidth);
54 painter->setPen(p);
55 }
56 else
57 {
58 Wt::WPen p(color);
59 p.setWidth(nodeStyle.PenWidth);
60 painter->setPen(p);
61 }
62
63 float diam = nodeStyle.ConnectionPointDiameter;
64 double const radius = 6.0;
65
66 Wt::WRectF boundary = model->captionVisible() ? Wt::WRectF(-diam, -diam, 2.0 * diam + geom.width(), 2.0 * diam + geom.height())
67 : Wt::WRectF(-diam, 0.0f, 2.0 * diam + geom.width(), diam + geom.height());
68
69 graphicsObject.setBoundingRect(boundary);
70
71 if (model->captionVisible())
72 {
73 unsigned int captionHeight = geom.captionHeight();
74
75 double captionRatio = (double)captionHeight / geom.height();
76
77 painter->setBrush(Wt::WColor(Wt::StandardColor::White));
78
79 painter->drawRect(boundary);
80
81 Wt::WPen p;
82 p.setColor(color);
83 p.setWidth(nodeStyle.PenWidth);
84
85 painter->setPen(p);
86 painter->drawLine(Wt::WPointF(-diam, geom.captionHeight()), Wt::WPointF(diam + geom.width(), geom.captionHeight()));
87 }
88 else
89 {
90 painter->drawRect(boundary);
91 }
92}
93
95 Wt::WPainter* painter,
96 WtNodeGeometry const& geom,
97 WtNodeState const& state,
98 WtNodeDataModel const* model,
99 WtFlowScene const& scene,
100 WtNodeGraphicsObject const& graphicsObject
101)
102{
103 WtNodeStyle const& nodeStyle = model->nodeStyle();
104
105 auto const& connectionStyle = WtStyleCollection::connectionStyle();
106
107 float diameter = nodeStyle.ConnectionPointDiameter;
108
109 auto reducedDiameter = diameter * 0.6;
110
111 std::vector<connectionPointData> pointsData;
112
113 for (PortType portType : {PortType::Out, PortType::In})
114 {
115 size_t n = state.getEntries(portType).size();
116
117 for (unsigned int i = 0; i < n; i++)
118 {
119 connectionPointData pointData;
120 pointData.portType = portType;
121
122 Wt::WPointF p = geom.portScenePosition(i, portType);
123
124 //TODO:Bug
125 auto const& dataType = model->dataType(portType, i);
126
127 bool canConnect = (state.getEntries(portType)[i].empty() ||
128 (portType == PortType::Out &&
130
131 double r = 1.0;
132
133 if (state.isReacting() && canConnect && portType == state.reactingPortType())
134 {
135 Wt::WPointF diff = Wt::WPointF(geom.draggingPos().x() - p.x(), geom.draggingPos().y() - p.y());
136
137 double dist = std::sqrt(diff.x() * diff.x() + diff.y() * diff.y());
138
139 bool typeConvertable = false;
140
141 {
142 if (portType == PortType::In)
143 {
144 typeConvertable = scene.registry().getTypeConverter(state.reactingDataType(), dataType) != nullptr;
145 }
146 else
147 {
148 typeConvertable = scene.registry().getTypeConverter(dataType, state.reactingDataType()) != nullptr;
149 }
150 }
151
152 if (state.reactingDataType().id == dataType.id || typeConvertable)
153 {
154 double const thres = 40.0;
155 r = (dist < thres) ?
156 (2.0 - dist / thres) :
157 1.0;
158 }
159 else
160 {
161 double const thres = 80.0;
162 r = (dist < thres) ?
163 (dist / thres) :
164 1.0;
165 }
166 }
167
168 //TODO: change the ports appearance according to the connection states
169 if (connectionStyle.useDataDefinedColors())
170 {
171 painter->setBrush(connectionStyle.normalColor(dataType.id));
172 }
173 else
174 {
175 painter->setBrush(nodeStyle.ConnectionPointColor);
176 }
177
178 double w = diameter * 0.4 * r;
179 double h = diameter * 0.8 * r;
180 Wt::WPointF vert[5];
181 vert[0] = Wt::WPointF(p.x() - w, p.y() - h);
182 vert[1] = Wt::WPointF(p.x() - w, p.y() + h);
183 vert[2] = Wt::WPointF(p.x() + w, p.y() + h);
184 vert[3] = Wt::WPointF(p.x() + (2.5 * w), p.y());
185 vert[4] = Wt::WPointF(p.x() + w, p.y() - h);
186
187 double dr = diameter * 1 * r;
188 Wt::WPointF diamond[4];
189 diamond[0] = Wt::WPointF(p.x(), p.y() + dr);
190 diamond[1] = Wt::WPointF(p.x() + dr, p.y());
191 diamond[2] = Wt::WPointF(p.x(), p.y() - dr);
192 diamond[3] = Wt::WPointF(p.x() - dr, p.y());
193
194 double odr = diameter * 1.1 * r;
195 double idr = diameter * 0.3 * r;
196 Wt::WPointF diamond_out[4];
197 diamond_out[0] = Wt::WPointF(p.x(), p.y() + odr);
198 diamond_out[1] = Wt::WPointF(p.x() + odr, p.y());
199 diamond_out[2] = Wt::WPointF(p.x(), p.y() - odr);
200 diamond_out[3] = Wt::WPointF(p.x() - odr, p.y());
201
202 Wt::WPointF diamond_inner[4];
203 diamond_inner[0] = Wt::WPointF(p.x(), p.y() + idr);
204 diamond_inner[1] = Wt::WPointF(p.x() + idr, p.y());
205 diamond_inner[2] = Wt::WPointF(p.x(), p.y() - idr);
206 diamond_inner[3] = Wt::WPointF(p.x() - idr, p.y());
207
208 double rx = reducedDiameter * r;
209 double ry = reducedDiameter * r;
210 Wt::WRectF drawRect = Wt::WRectF(p.x() - rx, p.y() - ry, 2 * rx, 2 * ry);
211
212 switch (dataType.shape)
213 {
214 case PortShape::Point:
215 painter->drawEllipse(drawRect);
216 pointData.portShape = PortShape::Point;
217 pointData.pointRect = drawRect;
218 pointData.portIndex = (PortIndex)i;
219 break;
221 painter->drawPolygon(diamond_out, 4);
222 painter->setBrush(Wt::StandardColor::White);
223 painter->drawPolygon(diamond_inner, 4);
224 pointData.portShape = PortShape::Bullet;
225 pointData.portIndex = (PortIndex)i;
226 pointData.diamond_out[0] = diamond_out[0];
227 pointData.diamond_out[1] = diamond_out[1];
228 pointData.diamond_out[2] = diamond_out[2];
229 pointData.diamond_out[3] = diamond_out[3];
230 break;
232 painter->drawPolygon(diamond, 4);
233 pointData.portShape = PortShape::Diamond;
234 pointData.portIndex = (PortIndex)i;
235 pointData.diamond[0] = diamond[0];
236 pointData.diamond[1] = diamond[1];
237 pointData.diamond[2] = diamond[2];
238 pointData.diamond[3] = diamond[3];
239 break;
240
241 default:
242 break;
243 }
244 pointsData.push_back(pointData);
245 }
246 };
247 graphicsObject.setPointsData(pointsData);
248}
249
251 Wt::WPainter* painter,
252 WtNodeGeometry const& geom,
253 WtNodeState const& state,
254 WtNodeDataModel const* model
255)
256{
257 WtNodeStyle const& nodeStyle = model->nodeStyle();
258
259 if (!model->captionVisible())
260 return;
261
262 std::string const& name = geom.strFormat(model->caption());
263
264 Wt::WFontMetrics metrics = painter->device()->fontMetrics();
265
266 Wt::WPointF position(0, 0);
267
268 Wt::WFont f = painter->font();
269
270 f.setWeight(Wt::FontWeight::Bold);
271
272 float diam = nodeStyle.ConnectionPointDiameter;
273
274 Wt::WRectF boundary(position, position);
275
276 painter->setFont(f);
277 painter->setPen(Wt::WPen(nodeStyle.FontColor));
278 painter->drawRect(boundary);
279 painter->drawText(boundary, Wt::AlignmentFlag::Left, Wt::WString(name));
280
281 f.setWeight(Wt::FontWeight::Normal);
282 painter->setFont(f);
283}
284
286 Wt::WPainter* painter,
287 WtNodeGeometry const& geom,
288 WtNodeDataModel const* model,
289 WtNodeGraphicsObject const& graphicsObject)
290{
291 WtNodeStyle const& nodeStyle = model->nodeStyle();
292
293 //auto color = graphicsObject.selectType() ? nodeStyle.SelectedBoundaryColor : nodeStyle.NormalBoundaryColor;
294 auto color = nodeStyle.NormalBoundaryColor;
295 if (graphicsObject.selectType() == 1)
296 {
297 color = nodeStyle.SelectedBoundaryColor;
298 }
299 if (graphicsObject.selectType() == 2)
300 {
301 color = nodeStyle.SelectedDragColor;
302 }
303
304 const Wt::WPen& pen = painter->pen();
305
306 if (model->captionVisible() && model->hotkeyEnabled())
307 {
308 unsigned int captionHeight = geom.captionHeight();
309 unsigned int keyWidth = geom.hotkeyWidth();
310 unsigned int keyShift = geom.hotkeyIncline();
311 unsigned int keyOffset = geom.hotkeyOffset();
312
313 float diam = nodeStyle.ConnectionPointDiameter;
314
315 Wt::WPen p(color);
316 p.setWidth(nodeStyle.PenWidth);
317 painter->setPen(p);
318
319 if (graphicsObject.hotKey0Hovered())
320 {
321 Wt::WPen p1(color);
322 p1.setWidth(nodeStyle.HoveredPenWidth);
323 painter->setPen(p1);
324 }
325 else
326 {
327 Wt::WPen p1(color);
328 p1.setWidth(nodeStyle.PenWidth);
329 painter->setPen(p1);
330 }
331
332 if (graphicsObject.isHotKey0Checked())
333 {
334 painter->setBrush(nodeStyle.GradientColor0);
335 }
336 else
337 {
338 painter->setBrush(nodeStyle.HotKeyColor0);
339 }
340
341 Wt::WPointF points[4];
342 points[0] = Wt::WPointF(geom.width() + diam - keyWidth - keyOffset, -diam);
343 points[1] = Wt::WPointF(geom.width() + diam - keyOffset, -diam);
344 //points[2] = Wt::WPointF(geom.width() + diam - keyShift - keyOffset, captionHeight);
345 //points[3] = Wt::WPointF(geom.width() + diam - keyWidth - keyShift - keyOffset, captionHeight);
346 points[2] = Wt::WPointF(geom.width() + diam - keyOffset, captionHeight);
347 points[3] = Wt::WPointF(geom.width() + diam - keyWidth - keyOffset, captionHeight);
348
349 //painter->drawPolygon(points, 4);
350
351 Wt::WRectF hotKey0Rect = Wt::WRectF(points[0], points[2]);
352
353 painter->drawRect(hotKey0Rect);
354
355 graphicsObject.setHotKey0BoundingRect(hotKey0Rect);
356
357 if (graphicsObject.hotKey1Hovered())
358 {
359 Wt::WPen p2(color);
360 p2.setWidth(nodeStyle.HoveredPenWidth);
361 painter->setPen(p2);
362 }
363 else
364 {
365 Wt::WPen p2(color);
366 p2.setWidth(nodeStyle.PenWidth);
367 painter->setPen(p2);
368 }
369
370 if (graphicsObject.isHotKey1Checked())
371 {
372 painter->setBrush(nodeStyle.GradientColor0);
373 }
374 else
375 {
376 painter->setBrush(nodeStyle.HotKeyColor1);
377 }
378
379 points[0] = Wt::WPointF(geom.width() + diam - keyWidth - keyOffset, -diam);
380 //points[1] = Wt::WPointF(geom.width() + diam - keyWidth - keyShift - keyOffset, captionHeight);
381 //points[2] = Wt::WPointF(geom.width() + diam - keyWidth - keyShift - keyWidth - keyOffset, captionHeight);
382 points[3] = Wt::WPointF(geom.width() + diam - keyWidth - keyWidth - keyOffset, -diam);
383
384 points[1] = Wt::WPointF(geom.width() + diam - keyWidth - keyOffset, captionHeight);
385 points[2] = Wt::WPointF(geom.width() + diam - keyWidth - keyWidth - keyOffset, captionHeight);
386
387 Wt::WRectF hotKey1Rect = Wt::WRectF(points[3], points[1]);
388
389 painter->drawRect(hotKey1Rect);
390
391 graphicsObject.setHotKey1BoundingRect(hotKey1Rect);
392
393 //painter->drawPolygon(points, 4);
394 }
395}
396
398 Wt::WPainter* painter,
399 WtNodeGeometry const& geom,
400 WtNodeState const& state,
401 WtNodeDataModel const* model)
402{
403 for (PortType portType : { PortType::Out, PortType::In })
404 {
405 auto const& nodeStyle = model->nodeStyle();
406
407 auto& entries = state.getEntries(portType);
408
409 size_t n = entries.size();
410
411 for (size_t i = 0; i < n; ++i)
412 {
413 Wt::WPointF p = geom.portScenePosition((PortIndex)i, portType);
414
415 if (entries[i].empty())
416 painter->setPen(nodeStyle.FontColorFaded);
417 else
418 painter->setPen(nodeStyle.FontColor);
419
420 std::string s;
421
422 if (model->portCaptionVisible(portType, (PortIndex)i))
423 s = model->portCaption(portType, (PortIndex)i);
424 else
425 s = model->dataType(portType, (PortIndex)i).name;
426
427 Wt::WFontMetrics metrics = painter->device()->fontMetrics();
428
429 Wt::WPointF topLeft, bottomRight;
430
431 switch (portType)
432 {
433 case PortType::In:
434 topLeft = Wt::WPointF(p.x() + 10, p.y() - metrics.height() / 3);
435 bottomRight = Wt::WPointF(p.x() + 50, p.y() + 6);
436 painter->drawText(Wt::WRectF(topLeft, bottomRight), Wt::AlignmentFlag::Left, Wt::WString(s));
437 break;
438
439 case PortType::Out:
440 topLeft = Wt::WPointF(p.x() - 50, p.y() - 6);
441 bottomRight = Wt::WPointF(p.x() - 10, p.y() + metrics.height() / 3);
442 painter->drawText(Wt::WRectF(topLeft, bottomRight), Wt::AlignmentFlag::Right, Wt::WString(s));
443 break;
444
445 default:
446 break;
447 }
448 }
449 }
450}
451
453 Wt::WPainter* painter,
454 WtNodeGeometry const& geom,
455 WtNodeDataModel const* model
456)
457{
458 if (model->resizable())
459 {
460 painter->setBrush(Wt::StandardColor::Gray);
461 painter->drawEllipse(geom.resizeRect());
462 }
463}
464
466 Wt::WPainter* painter,
467 WtNodeGeometry const& geom,
468 WtNodeDataModel const* model,
469 WtNodeGraphicsObject const& graphicsObject
470)
471{
472 auto modelValidationState = model->validationState();
473
474 if (modelValidationState != NodeValidationState::Valid)
475 {
476 WtNodeStyle const& nodeStyle = model->nodeStyle();
477
478 //auto color = graphicsObject.selectType() ? nodeStyle.SelectedBoundaryColor : nodeStyle.NormalBoundaryColor;
479 auto color = nodeStyle.NormalBoundaryColor;
480 if (graphicsObject.selectType() == 1)
481 {
482 color = nodeStyle.SelectedBoundaryColor;
483 }
484 if (graphicsObject.selectType() == 2)
485 {
486 color = nodeStyle.SelectedDragColor;
487 }
488
489 if (geom.hovered())
490 {
491 Wt::WPen p(color);
492 p.setWidth(Wt::WLength(nodeStyle.HoveredPenWidth, Wt::LengthUnit::Pixel));
493 painter->setPen(p);
494 }
495 else
496 {
497 Wt::WPen p(color);
498 p.setWidth(Wt::WLength(nodeStyle.PenWidth, Wt::LengthUnit::Pixel));
499 painter->setPen(p);
500 }
501
502 if (modelValidationState == NodeValidationState::Error)
503 {
504 painter->setBrush(nodeStyle.ErrorColor);
505 }
506 else
507 {
508 painter->setBrush(nodeStyle.WarningColor);
509 }
510
511 double const radius = 3.0;
512
513 float diam = nodeStyle.ConnectionPointDiameter;
514
515 Wt::WRectF boundary(-diam,
516 -diam + geom.height() - geom.validationHeight(),
517 2.0 * diam + geom.width(),
518 2.0 * diam + geom.validationHeight());
519
520 painter->drawRect(boundary);
521
522 painter->setBrush(Wt::StandardColor::Gray);
523
524 //No ErrorMsg
525 }
526}
527
528//WtNodeGraphicsObject
529
531 : _scene(scene)
532 , _node(node)
533 , _painter(painter)
534 , _locked(false)
535 , _flowNodeData(node.flowNodeData())
537{
538}
539
541
543{
544 return _node;
545}
546
548{
549 return _node;
550}
551
555
557{
558 return _node.nodeGeometry().boundingRect();
559}
560
562{
563 //prepareGeometryChange();
564}
565
567{
568 WtNodeState const& nodeState = _node.nodeState();
569
570 //for (PortType portType : {PortType::In, PortType::Out})
571 //{
572 // auto const& connectionEntries = nodeState.getEntries(portType);
573
574 // for (auto const& connections : connectionEntries)
575 // {
576 // for (auto& con : connections)
577 // con.second->getConnectionGraphicsObject().move();
578 // }
579 //}
580}
581
583{
584 _locked = locked;
585
586 //setFlag(QGraphicsItem::ItemIsMovable, !locked);
587 //setFlag(QGraphicsItem::ItemIsFocusable, !locked);
588 //setFlag(QGraphicsItem::ItemIsSelectable, !locked);
589}
590
591void WtNodeGraphicsObject::paint(Wt::WPainter* painter)
592{
594}
595
597{
598 return _origin;
599}
600
602{
603 _origin.setX(x);
604 _origin.setY(y);
605 _painter->translate(_origin);
606 _flowNodeData.setNodeOrigin(_origin);
608 _origin.setX(-x);
609 _origin.setY(-y);
610 _painter->translate(_origin);
611}
612
613void WtNodeGraphicsObject::setPos(Wt::WPointF pos)
614{
615 _origin = pos;
616 _painter->translate(_origin);
617 _flowNodeData.setNodeOrigin(_origin);
619 _origin.setX(-pos.x());
620 _origin.setY(-pos.y());
621 _painter->translate(_origin);
622}
int PortIndex
PortType
virtual ConnectionPolicy portOutConnectionPolicy(PortIndex) const
virtual std::string caption() const =0
virtual bool captionVisible() const
It is possible to hide caption in GUI.
virtual NodeDataType dataType(PortType portType, PortIndex portIndex) const =0
virtual bool hotkeyEnabled() const
WtNodeStyle const & nodeStyle() const
virtual bool portCaptionVisible(PortType, PortIndex) const
It is possible to hide port caption in GUI.
virtual std::string portCaption(PortType, PortIndex) const
Port caption is used in GUI to label individual ports.
virtual bool resizable() const
virtual NodeValidationState validationState() const
bool hovered() const
Definition WtNode.h:65
unsigned int captionHeight() const
Definition WtNode.cpp:516
Wt::WPointF portScenePosition(PortIndex index, PortType portType, Wt::WTransform const &t=Wt::WTransform()) const
Definition WtNode.cpp:270
unsigned int hotkeyIncline() const
Definition WtNode.h:51
Wt::WRectF resizeRect() const
Definition WtNode.cpp:167
unsigned int width() const
Definition WtNode.h:35
unsigned int hotkeyWidth() const
Definition WtNode.h:47
unsigned int height() const
Definition WtNode.h:31
unsigned int validationHeight() const
Definition WtNode.cpp:177
unsigned int hotkeyOffset() const
Definition WtNode.h:55
Wt::WPointF const & draggingPos() const
Definition WtNode.h:73
std::string strFormat(std::string str) const
Definition WtNode.cpp:193
void setPos(Wt::WPointF pos)
Wt::WRectF boundingRect() const
WtFlowNodeData & _flowNodeData
void setPointsData(std::vector< connectionPointData > p) const
void setBoundingRect(Wt::WRectF r) const
WtNodeGraphicsObject()=default
void setHotKey0BoundingRect(Wt::WRectF r) const
void paint(Wt::WPainter *painter)
void setHotKey1BoundingRect(Wt::WRectF r) const
WtNodeDataModel * nodeDataModel() const
Definition WtNode.cpp:727
WtNodeGraphicsObject const & nodeGraphicsObject() const
Definition WtNode.cpp:690
WtNodeState const & nodeState() const
Definition WtNode.cpp:717
WtNodeGeometry & nodeGeometry()
Definition WtNode.cpp:707
static void paint(Wt::WPainter *painter, WtNode &node, WtFlowScene const &scene)
static void drawResizeRect(Wt::WPainter *painter, WtNodeGeometry const &geom, WtNodeDataModel const *model)
static void drawEntryLabels(Wt::WPainter *painter, WtNodeGeometry const &geom, WtNodeState const &state, WtNodeDataModel const *model)
static void drawValidationRect(Wt::WPainter *painter, WtNodeGeometry const &geom, WtNodeDataModel const *model, WtNodeGraphicsObject const &graphicsObject)
static void drawConnectionPoints(Wt::WPainter *painter, WtNodeGeometry const &geom, WtNodeState const &state, WtNodeDataModel const *model, WtFlowScene const &scene, WtNodeGraphicsObject const &graphicsObject)
static void drawNodeRect(Wt::WPainter *painter, WtNodeGeometry const &geom, WtNodeDataModel const *model, WtNodeGraphicsObject const &graphicsObject)
static void drawModelName(Wt::WPainter *painter, WtNodeGeometry const &geom, WtNodeState const &state, WtNodeDataModel const *model)
static void drawHotKeys(Wt::WPainter *painter, WtNodeGeometry const &geom, WtNodeDataModel const *model, WtNodeGraphicsObject const &graphicsObject)
bool isReacting() const
Definition WtNode.cpp:651
std::vector< ConnectionPtrSet > const & getEntries(PortType) const
Definition WtNode.cpp:582
PortType reactingPortType() const
Definition WtNode.cpp:629
NodeDataType reactingDataType() const
Definition WtNode.cpp:634
Wt::WColor HotKeyColor1
Definition WtNodeStyle.h:58
Wt::WColor HotKeyColor0
Definition WtNodeStyle.h:57
Wt::WColor WarningColor
Definition WtNodeStyle.h:64
Wt::WColor ErrorColor
Definition WtNodeStyle.h:65
Wt::WColor GradientColor0
Definition WtNodeStyle.h:49
Wt::WColor SelectedBoundaryColor
Definition WtNodeStyle.h:47
float HoveredPenWidth
Definition WtNodeStyle.h:68
Wt::WColor FontColor
Definition WtNodeStyle.h:54
float ConnectionPointDiameter
Definition WtNodeStyle.h:70
Wt::WColor ConnectionPointColor
Definition WtNodeStyle.h:61
float PenWidth
Definition WtNodeStyle.h:67
Wt::WColor NormalBoundaryColor
Definition WtNodeStyle.h:46
Wt::WColor SelectedDragColor
Definition WtNodeStyle.h:48
static WtConnectionStyle const & connectionStyle()
std::string id
std::string name
Wt::WPointF diamond_out[4]
Wt::WPointF diamond[4]