nodeeditor_doxy
|
00001 #include <QtGui> 00002 00003 #include "nodeconnection.h" 00004 #include "nodeconnector.h" 00005 #include <math.h> 00006 00007 const qreal Pi = 3.14; 00008 00009 NodeConnection::~NodeConnection(){ 00010 if (this->mStartConnector != NULL) { 00011 this->mStartConnector->removeConnection(this); 00012 this->mStartConnector = NULL; 00013 } 00014 if (this->mEndConnector != NULL) { 00015 this->mEndConnector->removeConnection(this); 00016 this->mEndConnector = NULL; 00017 } 00018 //dw new 00019 if (scene() != NULL) { 00020 this->scene()->removeItem(this); 00021 } 00022 } 00023 00025 NodeConnection::NodeConnection(NodeConnector *startConnector, NodeConnector *endConnector, 00026 QGraphicsItem *parent, QGraphicsScene *scene, bool bidirectional) 00027 : QGraphicsPathItem(parent, scene) 00028 { 00029 //setCacheMode(DeviceCoordinateCache); 00030 00031 00032 mStartConnector = startConnector; 00033 mEndConnector = endConnector; 00034 setFlag(QGraphicsItem::ItemIsSelectable, true); 00035 00036 setBidirectional(bidirectional); 00037 00038 //line 00039 mColor = Qt::black; 00040 //path 00041 //mColor = Qt::black; 00042 setPen(QPen(mColor, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); 00043 arrowSize=10; 00044 00045 setZValue(-1000.0); 00046 00047 //dw new4 already done here, but why used in other places? 00048 /*/if (scene != NULL){ 00049 scene->addItem(this); 00050 }*/ 00051 00052 //dw new4: is this a problem? check it 00053 //setCacheMode(DeviceCoordinateCache); 00054 00055 QPointF controlPoint1; 00056 QPointF controlPoint2; 00057 recreatePath(controlPoint1, controlPoint2); 00058 } 00060 00062 QRectF NodeConnection::boundingRect() const 00063 { 00064 00065 /*//line 00066 qreal extra = (pen().width() + 20) / 2.0; 00067 00068 return QRectF(line().p1(), QSizeF(line().p2().x() - line().p1().x(), 00069 line().p2().y() - line().p1().y())) 00070 .normalized() 00071 .adjusted(-extra, -extra, extra, extra);*/ 00072 00073 00074 qreal extra = 3; 00075 return QGraphicsPathItem::boundingRect().normalized().adjusted(-extra, -extra, extra, extra); 00076 00077 } 00079 00081 QPainterPath NodeConnection::shape() const 00082 { 00083 /* 00084 //line 00085 QPainterPath path = QGraphicsLineItem::shape(); 00086 //path.addPolygon(arrowHead); 00087 return path; 00088 */ 00089 00090 //return QGraphicsPathItem::shape(); 00091 QPainterPath path = QGraphicsPathItem::shape(); 00092 //path.addPolygon(arrowHead); 00093 return path; 00094 } 00095 00096 void NodeConnection::updatePosition() { 00097 prepareGeometryChange(); 00098 update(); 00099 } 00100 00103 //void NodeConnection::recreatePath(QPointF& controlPoint1, QPointF& controlPoint2) 00104 //{ 00105 // //line 00106 // //QLineF line(mapFromItem(mStartConnector, 0, 0), mapFromItem(mEndConnector, 0, 0)); 00107 // //setLine(line); 00108 // 00109 // //cubic spline? 00110 // //QPointF a(mapFromItem(mStartConnector, 0, 0) - QPointF(mStartConnector->mRadius,0)); 00111 // //QPointF b(mapFromItem(mEndConnector, 0, 0) - QPointF(mStartConnector->mRadius,0)); 00112 // QPointF a(mapFromItem(mStartConnector, 0, 0)); 00113 // QPointF b(mapFromItem(mEndConnector, 0, 0)); 00114 // int dir1 = 1; 00115 // //we just think about the case where the connector is left, so just multiply dir where needed 00116 // if (mStartConnector->connectorAlignment() == NodeConnector::Right) { // right) { 00117 // dir1 = -1; 00118 // //a.setX(mapFromItem(mStartConnector, 0, 0).x() + mStartConnector->mRadius); 00119 // } 00120 // int dir2 = 1; 00121 // if (mEndConnector->connectorAlignment() == NodeConnector::Right) { // right) { 00122 // dir2 = -1; 00123 // //b.setX(mapFromItem(mEndConnector, 0, 0).x() + mStartConnector->mRadius); 00124 // } 00125 // 00126 // //define spline "mRadius" 00127 // qreal spline_mRadius = 100.0; 00128 // //dw new version 00129 // QPointF l; 00130 // QPointF r; 00131 // NodeConnector *ri; 00132 // NodeConnector *li; 00133 // bool aIsLeft = true; 00134 // qreal dist = QLineF(a, b).length(); 00135 // qreal diffx = abs(a.x() - b.x()); 00136 // qreal diffy = abs(a.y() - b.y()); 00137 // //QPointF newL; 00138 // //QPointF newR; 00139 // if (a.x() < b.x()) { 00140 // l = a; 00141 // r = b; 00142 // li = mStartConnector; 00143 // ri = mEndConnector; 00144 // } 00145 // else { 00146 // l = b; 00147 // r = a; 00148 // li = mEndConnector; 00149 // ri = mStartConnector; 00150 // aIsLeft = false; 00151 // } 00152 // /* 00153 // if (r.x() - l.x() > 5 * abs(r.y()-l.y()) && !li->right && ri->right) { 00154 // newL = l - QPointF(dist/2.0, dist/2.0); 00155 // newR = r + QPointF(dist/2.0, -dist/2.0); 00156 // } 00157 // else { 00158 // newL = l + (li->right ? 1.0 : -1.0) * QPointF(dist/2.0, 0); 00159 // newR = r + (ri->right ? 1.0 : -1.0) * QPointF(dist/2.0, 0); 00160 // } 00161 // */ 00162 // 00163 // 00164 // //QPointF controlPoint1; 00165 // //QPointF controlPoint2; 00166 // if (r.x() - l.x() > 5 * diffy && li->connectorAlignment() == NodeConnector::Left && ri->connectorAlignment() == NodeConnector::Right) { 00167 // controlPoint1 = l - QPointF(dist/4.0 + spline_mRadius , dist/4.0 + spline_mRadius); 00168 // controlPoint2 = r + QPointF(dist/4.0 + spline_mRadius, -dist/4.0 + spline_mRadius); 00169 // } 00170 // else { 00171 // controlPoint1 = l + (li->connectorAlignment() == NodeConnector::Right ? 1.0 : -1.0) * QPointF(dist/2 + (diffy > spline_mRadius ? spline_mRadius : 0), 0); 00172 // controlPoint2 = r + (ri->connectorAlignment() == NodeConnector::Right ? 1.0 : -1.0) * QPointF(dist/2 + (diffy > spline_mRadius ? spline_mRadius : 0), 0); 00173 // } 00174 // 00175 // 00176 // //dw new5 00177 // //dw667: was active 00178 // QPainterPath p(a); 00179 // //QPainterPath p = path(); 00180 // if (aIsLeft) { 00181 // p.cubicTo(controlPoint1, controlPoint2, b); 00182 // } 00183 // else { 00184 // p.cubicTo(controlPoint2, controlPoint1, b); 00185 // } 00186 // 00187 // 00188 // /* 00189 // //if directions are different and wrong direction, use y also 00190 // qreal diffy1 = 0; 00191 // qreal diffy2 = 0; 00192 // //y goes from top to bottom!!!! 00193 // if (dir1*dir2<0) { 00194 // if (a.y() < b.y()) { 00195 // diffy1 = spline_mRadius; 00196 // diffy2 = -spline_mRadius; 00197 // } 00198 // else { 00199 // diffy1 = -spline_mRadius; 00200 // diffy2 = spline_mRadius; 00201 // } 00202 // } 00203 // QPointF h1(a.x()-spline_mRadius*dir1, a.y() + diffy1); 00204 // QPointF h2(b.x()-spline_mRadius*dir2, b.y() + diffy1); 00205 // p.cubicTo(h1, h2, b); 00206 // */ 00207 // 00208 // 00209 // ////////////////////// 00210 // //arrow head 00211 // 00212 // /* 00213 // QPointF headStartP = p.pointAtPercent(p.percentAtLength(p.length() - mEndConnector->mRadius - arrowSize)); 00214 // QPointF headEndP = p.pointAtPercent(p.percentAtLength(p.length() - mEndConnector->mRadius)); 00215 // QLineF arrowMiddleLine(headStartP, headEndP); 00216 // //QLineF normHead = arrowMiddleLine.normalVector(); 00217 // arrowMiddleLine.unitVector(); 00218 // QPointF normHead(arrowMiddleLine.dy(), -arrowMiddleLine.dx()); 00219 // QPointF arrowP1 = headStartP + normHead * 0.4; 00220 // QPointF arrowP2 = headStartP - normHead * 0.4; 00221 // 00222 // arrowHead.clear(); 00223 // //dw668 00224 // arrowHead << headEndP << arrowP1 << arrowP2 /*<< headEndP*//*; 00225 // p.addPolygon(arrowHead); 00226 // */ 00227 // 00228 // //createArrows(p); 00229 // 00230 // ////////////////// 00231 // //dw667: was active 00232 // this->setPath(p); 00233 //} 00235 00236 00237 //new try: 00238 //dw667: DO ONLY CALL FROM PAINT METHOD!!! 00239 void NodeConnection::recreatePath(QPointF& controlPoint1, QPointF& controlPoint2) 00240 { 00241 QPointF a(mapFromItem(mStartConnector, 0, 0)); 00242 QPointF b(mapFromItem(mEndConnector, 0, 0)); 00243 00244 qreal dist = QLineF(a, b).length(); 00245 qreal diffx = abs(a.x() - b.x()); 00246 qreal diffy = abs(a.y() - b.y()); 00247 00248 QPointF left; 00249 QPointF right; 00250 NodeConnector* leftConn; 00251 NodeConnector* rightConn; 00252 if (a.x() < b.x()) { 00253 left = a; 00254 leftConn = mStartConnector; 00255 right = b; 00256 rightConn = mEndConnector; 00257 } 00258 else { 00259 left = b; 00260 leftConn = mEndConnector; 00261 right = a; 00262 rightConn = mStartConnector; 00263 } 00264 00265 QPointF bottom; 00266 QPointF top; 00267 NodeConnector* bottomConn; 00268 NodeConnector* topConn; 00269 if (a.y() < b.y()) { 00270 top = a; 00271 topConn = mStartConnector; 00272 bottom = b; 00273 bottomConn = mEndConnector; 00274 } 00275 else { 00276 top = b; 00277 topConn = mEndConnector; 00278 bottom = a; 00279 bottomConn = mStartConnector; 00280 } 00281 00282 00283 controlPoint1 = a; 00284 controlPoint2 = b; 00285 //how much to move control point from start or end point, default as used for simple case 00286 qreal moveX = 0.45 * diffx; 00287 qreal moveY = 0.45 * diffy; 00288 00289 QSizeF combinedSize(30,30); 00290 if (leftConn->parentItem() != NULL) { 00291 combinedSize.setWidth(leftConn->parentItem()->boundingRect().width()); 00292 combinedSize.setHeight(leftConn->parentItem()->boundingRect().height()); 00293 } 00294 else { 00295 combinedSize.setWidth(5 * leftConn->mRadius); 00296 combinedSize.setWidth(5 * leftConn->mRadius); 00297 } 00298 if (rightConn->parentItem() != NULL) { 00299 combinedSize.setWidth(combinedSize.width() + rightConn->parentItem()->boundingRect().width()); 00300 combinedSize.setHeight(combinedSize.height() + rightConn->parentItem()->boundingRect().height()); 00301 } 00302 else { 00303 combinedSize.setWidth(combinedSize.width() + 5 * rightConn->mRadius); 00304 combinedSize.setHeight(combinedSize.height() + 5 * rightConn->mRadius); 00305 } 00306 00307 00308 00309 if (leftConn->connectorAlignment() == rightConn->connectorAlignment() && leftConn->connectorAlignment() == NodeConnector::Left && right.x() - left.x() < combinedSize.width()/2.0) { 00310 controlPoint1.setX(controlPoint1.x() - moveY/2.0 /*- combinedSize.width()/2.0*/); 00311 controlPoint2.setX(controlPoint2.x() - moveY/2.0 /*- combinedSize.width()/2.0*/); 00312 } 00313 else if (leftConn->connectorAlignment() == rightConn->connectorAlignment() && leftConn->connectorAlignment() == NodeConnector::Right && right.x() - left.x() < combinedSize.width()/2.0) { 00314 controlPoint1.setX(controlPoint1.x() + moveY/2.0 /*+ combinedSize.width()/2.0*/); 00315 controlPoint2.setX(controlPoint2.x() + moveY/2.0 /*+ combinedSize.width()/2.0*/); 00316 } 00317 else if (leftConn->connectorAlignment() == rightConn->connectorAlignment() && leftConn->connectorAlignment() == NodeConnector::Top && bottom.y() - top.y() < combinedSize.height()/2.0) { 00318 controlPoint1.setY(controlPoint1.y() - moveX/2.0 /*- combinedSize.height()/2.0*/); 00319 controlPoint2.setY(controlPoint2.y() - moveX/2.0 /*- combinedSize.height()/2.0*/); 00320 } 00321 else if (leftConn->connectorAlignment() == rightConn->connectorAlignment() && leftConn->connectorAlignment() == NodeConnector::Bottom && bottom.y() - top.y() < combinedSize.height()/2.0) { 00322 controlPoint1.setY(controlPoint1.y() + moveX/2.0 /*+ combinedSize.height()/2.0*/); 00323 controlPoint2.setY(controlPoint2.y() + moveX/2.0 /*+ combinedSize.height()/2.0*/); 00324 } 00325 else 00326 //the simple case, they face each other the "good" way 00327 if (leftConn->connectorAlignment() != NodeConnector::Left && rightConn->connectorAlignment() != NodeConnector::Right 00328 && topConn->connectorAlignment() != NodeConnector::Top && bottomConn->connectorAlignment() != NodeConnector::Bottom) { 00329 00330 //very simple: straight line 00331 //controlPoint1 = a + 0.3 * (b-a); 00332 //controlPoint2 = a + 0.7 * (b-a); 00333 00334 controlPoint1 = a; 00335 controlPoint2 = b; 00336 //how much to move control point from start or end point 00337 qreal moveX = 0.45 * diffx; 00338 qreal moveY = 0.45 * diffy; 00339 if (dist > 5 * (mStartConnector->mRadius + arrowSize)) { 00340 /* does mess up good case because moves there too 00341 if (abs(diffx-diffy) > 0.3 * dist) { 00342 moveX += abs(diffx-diffy); 00343 moveY += abs(diffx-diffy); 00344 } 00345 */ 00346 00347 if (moveX < 3 * (mStartConnector->mRadius + arrowSize)) { 00348 moveX = 3 * (mStartConnector->mRadius + arrowSize); 00349 } 00350 if (moveY < 3 * (mStartConnector->mRadius + arrowSize)) { 00351 moveY = 3 * (mStartConnector->mRadius + arrowSize); 00352 } 00353 } 00354 00355 if (mStartConnector->connectorAlignment() == NodeConnector::Left) { 00356 controlPoint1.setX(controlPoint1.x() - moveX); 00357 } 00358 else if (mStartConnector->connectorAlignment() == NodeConnector::Right) { 00359 controlPoint1.setX(controlPoint1.x() + moveX); 00360 } 00361 else if (mStartConnector->connectorAlignment() == NodeConnector::Bottom) { 00362 controlPoint1.setY(controlPoint1.y() + moveY); 00363 } 00364 else if (mStartConnector->connectorAlignment() == NodeConnector::Top) { 00365 controlPoint1.setY(controlPoint1.y() - moveY); 00366 } 00367 00368 if (mEndConnector->connectorAlignment() == NodeConnector::Left) { 00369 controlPoint2.setX(controlPoint2.x() - moveX); 00370 } 00371 else if (mEndConnector->connectorAlignment() == NodeConnector::Right) { 00372 controlPoint2.setX(controlPoint2.x() + moveX); 00373 } 00374 else if (mEndConnector->connectorAlignment() == NodeConnector::Bottom) { 00375 controlPoint2.setY(controlPoint2.y() + moveY); 00376 } 00377 else if (mEndConnector->connectorAlignment() == NodeConnector::Top) { 00378 controlPoint2.setY(controlPoint2.y() - moveY); 00379 } 00380 } 00381 //the bad case, method needs cleanup 00382 else { 00383 controlPoint1 = a; 00384 controlPoint2 = b; 00385 qreal maxMove = 0.5 * dist; 00386 moveX = 0.5 * dist; 00387 moveY = 0.5 * dist; 00388 if (mStartConnector->parent != NULL) { 00389 maxMove = 1 * (mStartConnector->parent->boundingRect().width() + mStartConnector->parent->boundingRect().height()); 00390 } 00391 else if (mEndConnector->parent != NULL) { 00392 maxMove = 1 * (mEndConnector->parent->boundingRect().width() + mEndConnector->parent->boundingRect().height()); 00393 } 00394 if (moveX > maxMove) { 00395 moveX = maxMove + 0.1 * (moveX-maxMove); 00396 } 00397 if (moveY > maxMove) { 00398 moveY = maxMove + 0.1 * (moveY-maxMove); 00399 } 00400 if (mStartConnector->connectorAlignment() == NodeConnector::Left) { 00401 moveX *= -1; 00402 if ((mStartConnector == topConn) == (mStartConnector == rightConn)) { 00403 moveY *= -1;//relevantHeight; 00404 } 00405 } 00406 else if (mStartConnector->connectorAlignment() == NodeConnector::Right) { 00407 //moveX *= 1; 00408 if ((mStartConnector == topConn) == (mStartConnector == leftConn)) { 00409 moveY *= -1;//relevantHeight; 00410 } 00411 } 00412 else if (mStartConnector->connectorAlignment() == NodeConnector::Bottom) { 00413 //moveY *= 1; 00414 if ((mStartConnector == leftConn) == (mStartConnector == topConn)) { 00415 moveX *= -1; 00416 } 00417 } 00418 else if (mStartConnector->connectorAlignment() == NodeConnector::Top) { 00419 moveY *= -1; 00420 if ((mStartConnector == leftConn) == (mStartConnector == bottomConn)) { 00421 moveX *= -1; 00422 } 00423 } 00424 00425 /* 00426 if (mStartConnector->connectorAlignment() == mEndConnector->connectorAlignment()) { 00427 moveX *= 2; 00428 moveY *= 2; 00429 } 00430 */ 00431 00432 //ugly shit: handle some cases that don't look nice 00433 if (mEndConnector == topConn && topConn->connectorAlignment() == NodeConnector::Top && (bottomConn->connectorAlignment() == NodeConnector::Left || bottomConn->connectorAlignment() == NodeConnector::Right)) { 00434 moveY *= -1; 00435 //moveY = 0; 00436 } 00437 else if (mEndConnector == bottomConn && bottomConn->connectorAlignment() == NodeConnector::Bottom && (topConn->connectorAlignment() == NodeConnector::Left || topConn->connectorAlignment() == NodeConnector::Right)) { 00438 moveY *= -1; 00439 //moveY = 0; 00440 } 00441 else if (mEndConnector == leftConn && leftConn->connectorAlignment() == NodeConnector::Left && (rightConn->connectorAlignment() == NodeConnector::Top || rightConn->connectorAlignment() == NodeConnector::Bottom)) { 00442 moveX *= -1; 00443 //moveX = 0; 00444 } 00445 else if (mEndConnector == rightConn && rightConn->connectorAlignment() == NodeConnector::Right && (leftConn->connectorAlignment() == NodeConnector::Top || leftConn->connectorAlignment() == NodeConnector::Bottom)) { 00446 moveX *= -1; 00447 //moveX = 0; 00448 } 00449 00450 controlPoint1.setX(controlPoint1.x() + moveX); 00451 controlPoint1.setY(controlPoint1.y() + moveY); 00452 00453 00454 moveX = 0.5 * dist; 00455 moveY = 0.5 * dist; 00456 // if start was null, then it was already set to end. 00457 if (mStartConnector->parent != NULL && mEndConnector->parent != NULL) { 00458 maxMove = 1 * (mEndConnector->parent->boundingRect().width() + mEndConnector->parent->boundingRect().height()); 00459 } 00460 if (moveX > maxMove) { 00461 moveX = maxMove + 0.1 * (moveX-maxMove); 00462 } 00463 if (moveY > maxMove) { 00464 moveY = maxMove + 0.1 * (moveY-maxMove); 00465 } 00466 if (mEndConnector->connectorAlignment() == NodeConnector::Left) { 00467 moveX *= -1; 00468 if ((mEndConnector == topConn) == (mEndConnector == rightConn)) { 00469 moveY *= -1;//relevantHeight; 00470 } 00471 } 00472 else if (mEndConnector->connectorAlignment() == NodeConnector::Right) { 00473 //moveX *= 1; 00474 if ((mEndConnector == topConn) == (mEndConnector == leftConn)) { 00475 moveY *= -1;//relevantHeight; 00476 } 00477 } 00478 else if (mEndConnector->connectorAlignment() == NodeConnector::Bottom) { 00479 //moveY *= 1; 00480 if ((mStartConnector == leftConn) == (mStartConnector == topConn)) { 00481 moveX *= -1; 00482 } 00483 } 00484 else if (mEndConnector->connectorAlignment() == NodeConnector::Top) { 00485 moveY *= -1; 00486 if ((mStartConnector == leftConn) == (mStartConnector == bottomConn)) { 00487 moveX *= -1; 00488 } 00489 } 00490 00491 /* 00492 if (mStartConnector->connectorAlignment() == mEndConnector->connectorAlignment()) { 00493 moveX *= 2; 00494 moveY *= 2; 00495 }*/ 00496 00497 00498 //ugly shit: handle some cases that don't look nice 00499 if (mStartConnector == topConn && topConn->connectorAlignment() == NodeConnector::Top && (bottomConn->connectorAlignment() == NodeConnector::Left || bottomConn->connectorAlignment() == NodeConnector::Right)) { 00500 moveY *= -1; 00501 //moveY = 0; 00502 } 00503 else if (mStartConnector == bottomConn && bottomConn->connectorAlignment() == NodeConnector::Bottom && (topConn->connectorAlignment() == NodeConnector::Left || topConn->connectorAlignment() == NodeConnector::Right)) { 00504 moveY *= -1; 00505 //moveY = 0; 00506 } 00507 else if (mStartConnector == leftConn && leftConn->connectorAlignment() == NodeConnector::Left && (rightConn->connectorAlignment() == NodeConnector::Top || rightConn->connectorAlignment() == NodeConnector::Bottom)) { 00508 moveX *= -1; 00509 //moveX = 0; 00510 } 00511 else if (mStartConnector == rightConn && rightConn->connectorAlignment() == NodeConnector::Right && (leftConn->connectorAlignment() == NodeConnector::Top || leftConn->connectorAlignment() == NodeConnector::Bottom)) { 00512 moveX *= -1; 00513 //moveX = 0; 00514 } 00515 00516 controlPoint2.setX(controlPoint2.x() + moveX); 00517 controlPoint2.setY(controlPoint2.y() + moveY); 00518 } 00519 00520 00521 QPainterPath p(a); 00522 p.cubicTo(controlPoint1, controlPoint2, b); 00523 this->setPath(p); 00524 } 00525 00526 00527 //FIXME: width and length for arrow 00528 QPolygonF NodeConnection::createArrowPoly(QPainterPath& p, NodeConnector* conn) { 00529 float arrowStartPercentage; 00530 float arrowEndPercentage; 00531 00532 if (conn == mEndConnector) { 00533 arrowStartPercentage = p.percentAtLength(p.length() - conn->mRadius - arrowSize); 00534 arrowEndPercentage = p.percentAtLength(p.length() - conn->mRadius); 00535 } 00536 else { 00537 //assuming is start connector, should throw exception otherwise? 00538 arrowStartPercentage = p.percentAtLength(conn->mRadius + arrowSize); 00539 arrowEndPercentage = p.percentAtLength(conn->mRadius); 00540 } 00541 QPointF headStartP = p.pointAtPercent(arrowStartPercentage); 00542 QPointF headEndP = p.pointAtPercent(arrowEndPercentage); 00543 QLineF arrowMiddleLine(headStartP, headEndP); 00544 //QLineF normHead = arrowMiddleLine.normalVector(); 00545 arrowMiddleLine.unitVector(); 00546 QPointF normHead(arrowMiddleLine.dy(), -arrowMiddleLine.dx()); 00547 QPointF arrowP1 = headStartP + normHead * 0.4; 00548 QPointF arrowP2 = headStartP - normHead * 0.4; 00549 00550 QPolygonF arrowHeadEnd; 00551 arrowHeadEnd << headEndP << arrowP1 << arrowP2 /*<< headEndP*/; 00552 return arrowHeadEnd; 00553 } 00554 00555 00556 bool NodeConnection::setBidirectional(bool bidirectional) { 00557 mBidirectional = bidirectional && mStartConnector->connectorType() == NodeConnector::InOut && mEndConnector->connectorType() == NodeConnector::InOut; 00558 return mBidirectional; 00559 } 00560 bool NodeConnection::bidirectional() { 00561 return mBidirectional; 00562 } 00563 00564 00565 void NodeConnection::debugPaint(QPainter *painter, QPointF& controlPoint1, QPointF& controlPoint2) { 00566 00567 //dw debug 00568 static int i = 0, j=0, k=0; 00569 00570 QPen mPen = painter->pen(); 00571 QColor ctrlPtCol(i=(i+19)%256 , j=(j+51)%256, k=(k+11)%256); 00572 mPen.setColor(ctrlPtCol); 00573 painter->setPen(mPen); 00574 00575 //painter->drawPath(shape()); // to see item. 00576 painter->fillRect(boundingRect(), QColor(i=(i+19)%256 , j=(j+51)%256, k=(k+11)%256)); // to see item. 00577 00578 //painter->setPen(Qt::NoPen); 00579 painter->setBrush(ctrlPtCol); 00580 00581 //painter->drawPoint(controlPoint1); 00582 //painter->drawPoint(controlPoint2); 00583 painter->drawEllipse(controlPoint1.x()-2, controlPoint1.y()-2, 5, 5); 00584 painter->drawEllipse(controlPoint2.x()-2, controlPoint2.y()-2, 5, 5); 00585 } 00586 00587 00589 void NodeConnection::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *w) 00590 { 00591 Q_UNUSED(option); 00592 Q_UNUSED(w); 00593 00594 //dw 699: 00595 painter->setRenderHint(QPainter::Antialiasing); 00596 00597 if (mStartConnector == NULL || mEndConnector == NULL || mStartConnector->collidesWithItem(mEndConnector)) 00598 return; 00599 00600 //ugly, only used for debug draw 00601 QPointF controlPoint1; 00602 QPointF controlPoint2; 00603 recreatePath(controlPoint1, controlPoint2); 00604 00605 // FIXME:causes difference beteen debug draw and normal draw!!! 00606 //updatePosition(controlPoint1, controlPoint2); 00607 if (static_cast<DiagramScene*>(scene())->isDebugDraw()) { 00608 QPen origPen = painter->pen(); 00609 QBrush origBrush = painter->brush(); 00610 debugPaint(painter, controlPoint1, controlPoint2); 00611 painter->setPen(origPen); 00612 painter->setBrush(origBrush); 00613 } 00614 00615 QPen mPen = pen(); 00616 mPen.setColor(mColor); 00617 painter->setPen(mPen); 00618 //line 00619 //painter->setBrush(mColor); 00620 painter->setBrush(Qt::NoBrush); 00621 00622 if (isSelected()) 00623 painter->setPen(QPen(mColor, 1, Qt::DashLine)); 00624 00625 00626 00627 00628 //painter->drawLine(line()); 00629 00630 //cubic spline? 00631 QPainterPath& p = this->path(); 00632 painter->drawPath(p); 00633 00634 //fill 00635 painter->setBrush(mColor); 00636 00637 //test: 00638 QPolygonF arrowHeadEnd = createArrowPoly(p, mEndConnector); 00639 if (bidirectional()) { 00640 QPolygonF arrowHeadStart = createArrowPoly(p, mStartConnector); 00641 p.addPolygon(arrowHeadStart); 00642 painter->drawPolygon(arrowHeadStart); 00643 } 00644 //do this after creating other arrow, in case it matters in arrow calc on path 00645 p.addPolygon(arrowHeadEnd); 00646 painter->drawPolygon(arrowHeadEnd); 00647 00648 00649 /* 00650 //dw new4: what was it for, now commented out 00651 //dw668: activated again. otherwise painting of path had hollow head 00652 //dw reset brush, check again 00653 mPen = pen(); 00654 mPen.setColor(mColor); 00655 painter->setPen(mPen); 00656 painter->setBrush(mColor); 00657 painter->drawPolygon(arrowHead); 00658 */ 00659 } 00660