1 2 3 4 /************************************************************************\ 5 LabelledNode declaration 6 \************************************************************************/ 7 8 class Shaper; 9 10 #define LabelledNodeParent IlvListLabel 11 #define LabelledNodeParentPtr IlvListLabel* 12 class LabelledNode: public LabelledNodeParent { 13 private: 14 protected: 15 char* label_; 16 IlvColor* border_; 17 IlvShort bwidth_; 18 XeNodePtr xeNode_; 19 ShapeType shapeType_; 20 Shaper* shaper_; 21 22 virtual void drawShape(IlvDisplay* dpy, IlvPort* dst, 23 IlvPalette* palette, IlvTransformer* t, IlvRect& r) 24 ; 25 26 virtual void baseBoundingBox(IlvRect& r, IlvTransformer* t=0); 27 public: 28 LabelledNode(XeNodePtr xenode, IlvDisplay* dpy, const IlvPoint& p, char* lbl 29 , 30 IlvShort bwidth, IlvPalette* palette = nil); ~LabelledNode()31 ~LabelledNode() { ; } 32 void label(char*); label()33 char* label() { return (label_); } 34 void borderColor(char*); 35 36 void shape(ShapeType type); shapeType()37 ShapeType shapeType() { return shapeType_; } 38 borderWidth()39 IlvShort borderWidth() { return bwidth_; } borderWidth(IlvShort w)40 void borderWidth(IlvShort w) { bwidth_ = w; } 41 xeNode()42 XeNodePtr xeNode() { return xeNode_; } xeNode(XeNodePtr n)43 void xeNode(XeNodePtr n) { xeNode_ = n; } 44 45 virtual void draw(IlvPort* dst, IlvTransformer* t, IlvRegion* rect=0); 46 virtual void boundingBox(IlvRect& r, IlvTransformer* t=0); 47 virtual IlvBoolean contains(const IlvPoint& p, 48 const IlvPoint& tp, IlvTransformer* t); 49 virtual void computeRegion(IlvRegion& r, IlvTransformer* t=0); 50 51 static LabelledNode* makeShapedNode(XeNodePtr node, 52 IlvDisplay* dpy, 53 const ShapeType type, 54 const IlvPoint& p, 55 char* label, 56 IlvShort bwidth); 57 58 DeclareTypeInfo(); 59 }; 60 61 typedef enum { FixedPosition = 0x0, RelativePosition = 0x1 } ArcEndType; 62 63 /************************************************************************\ 64 LabelledArc declaration and implementation 65 \************************************************************************/ 66 67 68 typedef IlvLinkImage ArcRootClass; 69 70 class TextList; 71 72 #define RECURSIVE_BEZIER_ARCS 1 73 // IlvDisplay::drawArrow(dst, transform, start, end, atPos) requires 74 // atPos in the range [0.0,1.0]. 0.0 means draw the arrow at the 75 // beginning of line, 1.0 means draw at end... 76 77 const float ArrowAtStart = 0.0; 78 const float ArrowAtEnd = 1.0; 79 80 const int NodeBorderAllowance = 4; 81 82 #define LabelledArcParent IlvLinkImage 83 #define LabelledArcParentPtr IlvLinkImage* 84 class LabelledArc: public LabelledArcParent { 85 protected: 86 XeArcPtr arc; 87 char* label; 88 Boolean labelVisible; 89 90 char* labelColorString; 91 IlvColor* labelColor; 92 93 TextList* tlist; 94 #if RECURSIVE_BEZIER_ARCS 95 IlvPoint _points[7]; 96 IlvShort _nPoints; 97 IlvPoint _labelOrigin; 98 #else 99 IlvPoint _points[4]; 100 IlvInt _nPoints; 101 IlvPoint _labelOrigin; 102 #endif 103 104 IlvBoolean arrowContains(const IlvPoint& p, 105 const IlvPoint& tp, IlvTransformer*t=0); 106 107 virtual IlvBoolean arcContains(const IlvPoint& p, 108 const IlvPoint& tp, IlvTransformer*t=0) 109 { 110 IlvBoolean isIn; 111 isIn = IlvPointInLine(p, _points[0], _points[1]); 112 if (!isIn) { 113 isIn = arrowContains(p, tp, t); 114 } 115 return isIn; 116 } 117 118 virtual IlvBoolean labelContains(const IlvPoint& p, 119 const IlvPoint& tp, IlvTransformer*t=0) 120 { 121 IlvRect r; 122 labelBoundingBox(r, t); 123 IlvBoolean isIn; 124 if (t) { 125 isIn = r.contains(tp); 126 } else { 127 isIn = r.contains(p); 128 } 129 return isIn; 130 } 131 132 // calculate the origination point for the label, using the 133 // indicated transformation 134 virtual void getLabelOrigin(IlvPoint& origin, IlvTransformer* t=0) 135 { 136 IlvRect r; 137 arcBoundingBox(r, t); 138 origin.move(r.centerx(), r.centery()); 139 } 140 141 virtual void arrowPoints(IlvPoint* points, IlvTransformer* t=0) 142 { 143 // This should really calculate the points then apply the transformer... 144 IlvPoint from = _points[0], to = _points[1]; 145 if (t) { 146 t->apply(from); 147 t->apply(to); 148 } 149 IlvComputeArrow(from, to, ArrowAtEnd, points); 150 } 151 152 virtual void arrowBoundingBox(IlvRect& r, IlvTransformer* t=0) 153 { 154 IlvPoint pts[3]; 155 arrowPoints(pts, t); 156 r.resize(0,0); 157 r.move(pts[0]); 158 r.add(pts[1]); 159 r.add(pts[2]); 160 } 161 162 virtual void arcBoundingBox(IlvRect& r, IlvTransformer* t=0) 163 { 164 r.move(_points[0]); 165 r.resize(0,0); 166 r.add(_points[1]); 167 if (t) t->apply(r); 168 IlvRect arrowBox; 169 arrowBoundingBox(arrowBox, t); 170 if (arrowBox.w() != 0 && arrowBox.h() != 0) { 171 r.add(arrowBox); 172 } 173 } 174 // find the label's origin relative to the non-transformed bounding 175 // box, then calculate the label's bounding box using the 176 // indicated transformation... 177 virtual void labelBoundingBox(IlvRect& r, IlvTransformer* t=0); 178 179 virtual void drawArrow(IlvPort* dst, IlvTransformer* t=0, IlvRegion* = 0) 180 { 181 IlvPoint start = _points[0], end = _points[1]; 182 if (t) { 183 t->apply(start); 184 t->apply(end); 185 } 186 getDisplay()->drawArrow(dst, getPalette(), start, end, ArrowAtEnd); 187 } 188 189 virtual void drawArc(IlvPort* dst, IlvTransformer* t=0, IlvRegion* rect=0); 190 191 virtual void drawLabel(IlvPort* dst, IlvTransformer* t, IlvRegion* clip=0); 192 193 virtual void computePoints(IlvGraphic* f, IlvGraphic* t); 194 195 public: 196 LabelledArc(XeArcPtr owner, IlvDisplay* dpy, char* lbl, 197 UIPtr tail, UIPtr head, Boolean showLabel = True); 198 ~LabelledArc(); 199 owner()200 XeArcPtr owner() { return arc; } 201 getLabel()202 char* getLabel() { return label; } 203 void setLabel(char* s); 204 getLabelColor()205 char* getLabelColor() { return labelColorString; } 206 void setLabelColor(char* c); 207 getLabelVisible()208 Boolean getLabelVisible() { return labelVisible; } 209 void setLabelVisible(Boolean v); 210 211 virtual IlvBoolean contains(const IlvPoint& p, 212 const IlvPoint& tp, IlvTransformer*t =0); 213 virtual void draw(IlvPort* dst, IlvTransformer* t=0, IlvRegion* rect=0); 214 virtual void boundingBox(IlvRect&, IlvTransformer*t =0); 215 virtual void computeRegion(IlvRegion& r, IlvTransformer* t); 216 217 DeclareTypeInfo(); 218 219 }; 220 221 /************************************************************************\ 222 sibling computation code -- perhaps this should be a nested class of arcs 223 \************************************************************************/ 224 225 class SiblingList { 226 protected: 227 XeArcPtr* arcs; 228 int nSlots; 229 int nArcs; 230 231 void listAppend(XeArcPtr sib); 232 void listRemove(XeArcPtr sib); 233 public: SiblingList()234 SiblingList() { nSlots = 0; nArcs = 0; arcs = nil; } ~SiblingList()235 ~SiblingList() { delete arcs; } 236 count()237 int count() { return nArcs; } max()238 int max() { return nSlots; } 239 240 void insert(XeArcPtr sib); 241 void remove(XeArcPtr sib); 242 int rank(XeArcPtr); 243 isSibling(XeArcPtr sib)244 IlvBoolean isSibling(XeArcPtr sib) 245 { 246 IlvBoolean isSib = IlvFalse; 247 for(int i = 0; i < nArcs; i++) { 248 if (arcs[i] == sib) { 249 isSib = IlvTrue; 250 break; 251 } 252 } 253 return isSib; 254 } 255 }; 256 257 258 #if RECURSIVE_BEZIER_ARCS 259 const IlvFloat RankedArcArrowPosition = ArrowAtEnd; 260 #else 261 const IlvFloat RankedArcArrowPosition = 0.6; 262 #endif 263 264 #define RankedArcParent LabelledArc 265 #define RankedArcParentPtr LabelledArc* 266 class RankedArc: public RankedArcParent { 267 protected: 268 269 IlvGraphic* _selfNode; 270 #if !RECURSIVE_BEZIER_ARCS 271 EllipseInfo* _eInfo; 272 #endif 273 int currentRank; 274 275 // Compute the control points for our curve based on rank and 276 // current position of head and tail of arc 277 virtual void computePoints(IlvGraphic* f, IlvGraphic* t); 278 279 virtual void arrowPoints(IlvPoint* points, IlvTransformer* t=0) { 280 // This should really calculate the points then apply the transformer... 281 IlvPoint from, to; 282 IlvFloat arrowPos = ArrowAtEnd; 283 if (currentRank == 0 && !selfish()) { 284 RankedArcParent::arrowPoints(points, t); 285 return; 286 } 287 if (selfish()) { 288 #if RECURSIVE_BEZIER_ARCS 289 arrowPos = RankedArcArrowPosition; 290 from = _points[5]; 291 to = _points[6]; 292 #else 293 arrowPos = RankedArcArrowPosition; 294 from = _eInfo->startArrow(); 295 to = _eInfo->endArrow(); 296 #endif 297 } else { 298 from = _points[2]; 299 to = _points[3]; 300 } 301 if (t) { 302 t->apply(from); 303 t->apply(to); 304 } 305 IlvComputeArrow(from, to, arrowPos, points); 306 } 307 computeRank()308 int computeRank() { 309 return owner()->siblings() ? owner()->siblings()->rank(owner()): 0; 310 } 311 selfish()312 IlvBoolean selfish() { return _selfNode ? IlvTrue : IlvFalse; } 313 314 virtual IlvBoolean arcContains(const IlvPoint& p, 315 const IlvPoint& tp, IlvTransformer*t=0) 316 { 317 IlvBoolean isIn = IlvFalse; 318 currentRank = computeRank(); 319 IlvGraphic* tail = getFrom(); 320 IlvGraphic* head = getTo(); 321 computePoints(tail, head); 322 if (currentRank == 0 && !selfish()) { 323 isIn = RankedArcParent::arcContains(p, tp, t); 324 } else { 325 if (t) { 326 #if RECURSIVE_BEZIER_ARCS 327 IlvPoint points[8]; 328 #else 329 IlvPoint points[4]; 330 #endif 331 for (int i = 0; i < _nPoints; i++) { 332 points[i] = _points[i]; 333 t->apply(points[i]); 334 } 335 // check the "transformed point" supplied by Views manager... 336 #if RECURSIVE_BEZIER_ARCS 337 isIn = IlvPointInSpline(tp, _nPoints, points); 338 #else 339 if (selfish()) { 340 IlvRect r = _eInfo->rect(); 341 t->apply(r); 342 isIn = PointOnArc(tp, r, _eInfo->startAngle(), 343 _eInfo->deltaAngle(), /* tolerance */ 2); 344 } else { 345 isIn = IlvPointInSpline(tp, _nPoints, points); 346 } 347 #endif 348 } else { 349 #if RECURSIVE_BEZIER_ARCS 350 isIn = IlvPointInSpline(p, _nPoints, _points); 351 #else 352 if (selfish()) { 353 isIn = PointOnArc(p, _eInfo->rect(), _eInfo->startAngle(), 354 _eInfo->deltaAngle(), /* tolerance */ 2); 355 } else { 356 isIn = IlvPointInSpline(p, _nPoints, _points); 357 } 358 #endif 359 } 360 if (!isIn) { 361 isIn = arrowContains(p, tp, t); 362 } 363 } 364 return isIn; 365 } 366 367 // calculate the origination point for the label, using the 368 // indicated transformation 369 virtual void getLabelOrigin(IlvPoint& origin, IlvTransformer* t=0) 370 { 371 currentRank = computeRank(); 372 IlvGraphic* tail = getFrom(); 373 IlvGraphic* head = getTo(); 374 computePoints(tail, head); 375 if (currentRank == 0 && !selfish()) { 376 RankedArcParent::getLabelOrigin(origin, t); 377 } else { 378 origin = _labelOrigin; 379 if (t) { 380 t->apply(origin); 381 } 382 } 383 } 384 385 virtual void arcBoundingBox(IlvRect& r, IlvTransformer* t=0) 386 { 387 currentRank = computeRank(); 388 IlvGraphic* tail = getFrom(); 389 IlvGraphic* head = getTo(); 390 computePoints(tail, head); 391 if (currentRank == 0 && !selfish()) { 392 RankedArcParent::arcBoundingBox(r, t); 393 } else { 394 #if RECURSIVE_BEZIER_ARCS 395 r.move(_points[0]); 396 r.resize(0,0); 397 r.add(_points[1]); 398 r.add(_points[2]); 399 r.add(_points[3]); 400 if (selfish()) { // only valid for self arcs... 401 r.add(_points[4]); 402 r.add(_points[5]); 403 r.add(_points[6]); 404 } 405 #else 406 if (selfish()) { 407 IlvComputeArcBBox(_eInfo->rect(), 408 _eInfo->startAngle(), 409 _eInfo->deltaAngle(), 410 r); 411 } else { 412 r.move(_points[0]); 413 r.resize(0,0); 414 r.add(_points[1]); 415 r.add(_points[2]); 416 r.add(_points[3]); 417 } 418 #endif 419 IlvRect arrowBox; 420 arrowBoundingBox(arrowBox, 0); 421 r.add(arrowBox); 422 if (t) t->apply(r); 423 } 424 } 425 426 virtual void drawArc(IlvPort* dst, IlvTransformer* t=0, IlvRegion* rect=0) 427 { 428 currentRank = computeRank(); 429 IlvGraphic* tail = getFrom(); 430 IlvGraphic* head = getTo(); 431 computePoints(tail, head); 432 if (currentRank == 0 && !selfish()) { 433 RankedArcParent::drawArc(dst, t, rect); 434 } else { 435 // how do we draw the arrow??? 436 drawArrow(dst, t, rect); 437 drawRankedArc(currentRank, dst, t, rect); 438 } 439 } 440 441 virtual void drawRankedArc(int rank, IlvPort* dst, IlvTransformer* t=0, IlvR 442 egion* rect=0) 443 { 444 #if RECURSIVE_BEZIER_ARCS 445 if (selfish() || rank > 0) { 446 if (!t) { 447 getDisplay()->drawBezier(dst, getPalette(), _nPoints, _points); 448 } else { 449 IlvPoint points[8]; 450 for (int i = 0; i < _nPoints; i++) { 451 points[i] = _points[i]; 452 t->apply(points[i]); 453 } 454 getDisplay()->drawBezier(dst, getPalette(), _nPoints, points); 455 } 456 } else { 457 // shouldn't reach this point... 458 RankedArcParent::drawArc(dst, t, rect); 459 } 460 #else 461 if (selfish()) { 462 IlvRect r = _eInfo->rect(); 463 if (t) t->apply(r); 464 getDisplay()->drawArc(dst, getPalette(), r, 465 (IlvFloat) _eInfo->startAngle(), 466 (IlvFloat) _eInfo->deltaAngle()); 467 } else if (rank > 0) { 468 if (t) { 469 IlvPoint points[4]; 470 for (int i = 0; i < _nPoints; i++) { 471 points[i] = _points[i]; 472 t->apply(points[i]); 473 } 474 getDisplay()->drawBezier(dst, getPalette(), _nPoints, points); 475 } else { 476 getDisplay()->drawBezier(dst, getPalette(), _nPoints, _points); 477 } 478 } else { 479 // shouldn't reach this point... 480 RankedArcParent::drawArc(dst, t, rect); 481 } 482 #endif 483 } 484 485 virtual void drawArrow(IlvPort* dst, IlvTransformer* t=0, IlvRegion* r=0) 486 { 487 IlvBoolean selfArc = selfish(); 488 if (!selfArc && currentRank == 0) { 489 RankedArcParent::drawArrow(dst, t, r); 490 } else { 491 IlvPoint start, end; 492 IlvFloat arrowPos = ArrowAtEnd; 493 #if RECURSIVE_BEZIER_ARCS 494 if (selfArc) { 495 start = _points[5]; 496 end = _points[6]; 497 arrowPos = RankedArcArrowPosition; 498 } else { 499 start = _points[2]; 500 end = _points[3]; 501 } 502 #else 503 if (selfArc) { 504 start = _eInfo->startArrow(); 505 end = _eInfo->endArrow(); 506 arrowPos = RankedArcArrowPosition; 507 } else { 508 // we use the control points of our spline to determine direction 509 // and "slope" of arrow's center... 510 start = _points[2]; 511 end = _points[3]; 512 } 513 #endif 514 if (t) { 515 t->apply(start); 516 t->apply(end); 517 } 518 getDisplay()->drawArrow(dst, getPalette(), start, end, arrowPos); 519 } 520 } 521 522 523 public: 524 RankedArc(XeArcPtr owner, IlvDisplay* dpy, char* lbl, 525 UIPtr tail, UIPtr head, Boolean showLabel = True); ~RankedArc()526 ~RankedArc() { 527 _nPoints = 0; 528 #if !RECURSIVE_BEZIER_ARCS 529 if (_selfNode) 530 delete _eInfo; 531 #endif 532 } 533 534 DeclareTypeInfo(); 535 536 }; 537 538 539 540