1/** 2 * Copyright (c) 2006-2015, JGraph Ltd 3 */ 4 5/** 6 * Registers shapes. 7 */ 8(function() 9{ 10 // LATER: Use this to implement striping 11 function paintTableBackground(state, c, x, y, w, h, r) 12 { 13 if (state != null) 14 { 15 var graph = state.view.graph; 16 var start = graph.getActualStartSize(state.cell); 17 var rows = graph.model.getChildCells(state.cell, true); 18 19 if (rows.length > 0) 20 { 21 var events = false; 22 23 if (this.style != null) 24 { 25 events = mxUtils.getValue(this.style, mxConstants.STYLE_POINTER_EVENTS, '1') == '1'; 26 } 27 28 if (!events) 29 { 30 c.pointerEvents = false; 31 } 32 33 var evenRowColor = mxUtils.getValue(state.style, 34 'evenRowColor', mxConstants.NONE); 35 var oddRowColor = mxUtils.getValue(state.style, 36 'oddRowColor', mxConstants.NONE); 37 var evenColColor = mxUtils.getValue(state.style, 38 'evenColumnColor', mxConstants.NONE); 39 var oddColColor = mxUtils.getValue(state.style, 40 'oddColumnColor', mxConstants.NONE); 41 var cols = graph.model.getChildCells(rows[0], true); 42 43 // Paints column backgrounds 44 for (var i = 0; i < cols.length; i++) 45 { 46 var clr = (mxUtils.mod(i, 2) == 1) ? evenColColor : oddColColor; 47 var geo = graph.getCellGeometry(cols[i]); 48 49 if (geo != null && clr != mxConstants.NONE) 50 { 51 c.setFillColor(clr); 52 c.begin(); 53 c.moveTo(x + geo.x, y + start.y); 54 55 if (r > 0 && i == cols.length - 1) 56 { 57 c.lineTo(x + geo.x + geo.width - r, y); 58 c.quadTo(x + geo.x + geo.width, y, x + geo.x + geo.width, y + r); 59 c.lineTo(x + geo.x + geo.width, y + h - r); 60 c.quadTo(x + geo.x + geo.width, y + h, x + geo.x + geo.width - r, y + h); 61 } 62 else 63 { 64 c.lineTo(x + geo.x + geo.width, y + start.y); 65 c.lineTo(x + geo.x + geo.width, y + h - start.height); 66 } 67 68 c.lineTo(x + geo.x, y + h); 69 c.close(); 70 c.fill(); 71 } 72 } 73 74 // Paints row backgrounds 75 for (var i = 0; i < rows.length; i++) 76 { 77 var clr = (mxUtils.mod(i, 2) == 1) ? evenRowColor : oddRowColor; 78 var geo = graph.getCellGeometry(rows[i]); 79 80 if (geo != null && clr != mxConstants.NONE) 81 { 82 var b = (i == rows.length - 1) ? y + h : y + geo.y + geo.height; 83 c.setFillColor(clr); 84 85 c.begin(); 86 c.moveTo(x + start.x, y + geo.y); 87 c.lineTo(x + w - start.width, y + geo.y); 88 89 if (r > 0 && i == rows.length - 1) 90 { 91 c.lineTo(x + w, b - r); 92 c.quadTo(x + w, b, x + w - r, b); 93 c.lineTo(x + r, b); 94 c.quadTo(x, b, x, b - r); 95 } 96 else 97 { 98 c.lineTo(x + w - start.width, b); 99 c.lineTo(x + start.x, b); 100 } 101 102 c.close(); 103 c.fill(); 104 } 105 } 106 } 107 } 108 }; 109 110 // Table Shape 111 function TableShape() 112 { 113 mxSwimlane.call(this); 114 }; 115 116 mxUtils.extend(TableShape, mxSwimlane); 117 118 TableShape.prototype.getLabelBounds = function(rect) 119 { 120 var start = this.getTitleSize(); 121 122 if (start == 0) 123 { 124 return mxShape.prototype.getLabelBounds.apply(this, arguments); 125 } 126 else 127 { 128 return mxSwimlane.prototype.getLabelBounds.apply(this, arguments); 129 } 130 }; 131 132 TableShape.prototype.paintVertexShape = function(c, x, y, w, h) 133 { 134 // LATER: Split background to add striping 135 //paintTableBackground(this.state, c, x, y, w, h); 136 137 var start = this.getTitleSize(); 138 139 if (start == 0) 140 { 141 mxRectangleShape.prototype.paintBackground.apply(this, arguments); 142 } 143 else 144 { 145 mxSwimlane.prototype.paintVertexShape.apply(this, arguments); 146 c.translate(-x, -y); 147 } 148 149 this.paintForeground(c, x, y, w, h); 150 }; 151 152 TableShape.prototype.paintForeground = function(c, x, y, w, h) 153 { 154 if (this.state != null) 155 { 156 var flipH = this.flipH; 157 var flipV = this.flipV; 158 159 if (this.direction == mxConstants.DIRECTION_NORTH || this.direction == mxConstants.DIRECTION_SOUTH) 160 { 161 var tmp = flipH; 162 flipH = flipV; 163 flipV = tmp; 164 } 165 166 // Negative transform to avoid save/restore 167 c.rotate(-this.getShapeRotation(), flipH, flipV, x + w / 2, y + h / 2); 168 169 s = this.scale; 170 x = this.bounds.x / s; 171 y = this.bounds.y / s; 172 w = this.bounds.width / s; 173 h = this.bounds.height / s; 174 this.paintTableForeground(c, x, y, w, h); 175 } 176 }; 177 178 TableShape.prototype.paintTableForeground = function(c, x, y, w, h) 179 { 180 var graph = this.state.view.graph; 181 var start = graph.getActualStartSize(this.state.cell); 182 var rows = graph.model.getChildCells(this.state.cell, true); 183 184 if (rows.length > 0) 185 { 186 var rowLines = mxUtils.getValue(this.state.style, 187 'rowLines', '1') != '0'; 188 var columnLines = mxUtils.getValue(this.state.style, 189 'columnLines', '1') != '0'; 190 var geo = graph.getCellGeometry(rows[0]); 191 var cells = graph.model.getChildCells(rows[0], true); 192 var rowData = [{y: (geo != null) ? geo.y + geo.height : 0, 193 x: 0, cells: cells, colspans: []}]; 194 195 // Paints row lines 196 if (rowLines) 197 { 198 for (var i = 1; i < rows.length; i++) 199 { 200 geo = graph.getCellGeometry(rows[i]); 201 202 var data = {y: 0, cells: graph.model. 203 getChildCells(rows[i], true), 204 colspans: []}; 205 rowData.push(data); 206 207 if (geo != null) 208 { 209 data.y = geo.y + geo.height; 210 211 c.begin(); 212 c.moveTo(x + start.x, y + geo.y); 213 var tw = 0; 214 215 for (j = 0; j < data.cells.length; j++) 216 { 217 if (graph.model.isVisible(data.cells[j])) 218 { 219 tw = data.x; 220 } 221 else 222 { 223 if (tw > 0) 224 { 225 c.lineTo(x + tw - start.width, y + geo.y); 226 } 227 228 c.moveTo(x + geo.x + geo.width + start.x, y + geo.y); 229 tw = 0; 230 } 231 } 232 233 c.lineTo(x + w - start.width, y + geo.y); 234 c.end(); 235 c.stroke(); 236 } 237 } 238 } 239 240 // Paints column lines 241 if (columnLines) 242 { 243 var cols = rowData[0].cells; 244 245 for (var i = 1; i < cols.length; i++) 246 { 247 geo = graph.getCellGeometry(cols[i]); 248 249 if (geo != null) 250 { 251 c.begin(); 252 c.moveTo(x + geo.x + start.x, y + start.y); 253 var th = 0; 254 255 for (var j = 0; j < rowData.length; j++) 256 { 257 var data = rowData[j]; 258 var colspan = (i == 1) ? parseInt(graph.getCurrentCellStyle( 259 data.cells[i - 1], true)['colspan'] || 1) : 260 rowData[j].colspans[i - 1]; 261 262 data.colspans[i] = colspan - 1; 263 264 if (data.colspans[i] < 1) 265 { 266 data.colspans[i] = parseInt(graph.getCurrentCellStyle( 267 data.cells[i], true)['colspan'] || 1); 268 th = data.y; 269 } 270 else 271 { 272 if (th > 0) 273 { 274 c.lineTo(x + geo.x + start.x, y + th - start.height); 275 } 276 277 c.moveTo(x + geo.x + start.x, y + data.y); 278 th = 0; 279 } 280 } 281 282 c.lineTo(x + geo.x + start.x, y + h - start.height); 283 c.end(); 284 c.stroke(); 285 } 286 } 287 } 288 } 289 }; 290 291 mxCellRenderer.registerShape('table', TableShape); 292 293 // Cube Shape, supports size style 294 function CubeShape() 295 { 296 mxCylinder.call(this); 297 }; 298 mxUtils.extend(CubeShape, mxCylinder); 299 CubeShape.prototype.size = 20; 300 CubeShape.prototype.darkOpacity = 0; 301 CubeShape.prototype.darkOpacity2 = 0; 302 303 CubeShape.prototype.paintVertexShape = function(c, x, y, w, h) 304 { 305 var s = Math.max(0, Math.min(w, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size))))); 306 var op = Math.max(-1, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'darkOpacity', this.darkOpacity)))); 307 var op2 = Math.max(-1, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'darkOpacity2', this.darkOpacity2)))); 308 c.translate(x, y); 309 310 c.begin(); 311 c.moveTo(0, 0); 312 c.lineTo(w - s, 0); 313 c.lineTo(w, s); 314 c.lineTo(w, h); 315 c.lineTo(s, h); 316 c.lineTo(0, h - s); 317 c.lineTo(0, 0); 318 c.close(); 319 c.end(); 320 c.fillAndStroke(); 321 322 if (!this.outline) 323 { 324 c.setShadow(false); 325 326 if (op != 0) 327 { 328 c.setFillAlpha(Math.abs(op)); 329 c.setFillColor((op < 0) ? '#FFFFFF' : '#000000'); 330 c.begin(); 331 c.moveTo(0, 0); 332 c.lineTo(w - s, 0); 333 c.lineTo(w, s); 334 c.lineTo(s, s); 335 c.close(); 336 c.fill(); 337 } 338 339 if (op2 != 0) 340 { 341 c.setFillAlpha(Math.abs(op2)); 342 c.setFillColor((op2 < 0) ? '#FFFFFF' : '#000000'); 343 c.begin(); 344 c.moveTo(0, 0); 345 c.lineTo(s, s); 346 c.lineTo(s, h); 347 c.lineTo(0, h - s); 348 c.close(); 349 c.fill(); 350 } 351 352 c.begin(); 353 c.moveTo(s, h); 354 c.lineTo(s, s); 355 c.lineTo(0, 0); 356 c.moveTo(s, s); 357 c.lineTo(w, s); 358 c.end(); 359 c.stroke(); 360 } 361 }; 362 CubeShape.prototype.getLabelMargins = function(rect) 363 { 364 if (mxUtils.getValue(this.style, 'boundedLbl', false)) 365 { 366 var s = parseFloat(mxUtils.getValue(this.style, 'size', this.size)) * this.scale; 367 368 return new mxRectangle(s, s, 0, 0); 369 } 370 371 return null; 372 }; 373 374 mxCellRenderer.registerShape('cube', CubeShape); 375 376 var tan30 = Math.tan(mxUtils.toRadians(30)); 377 var tan30Dx = (0.5 - tan30) / 2; 378 379 mxCellRenderer.registerShape('isoRectangle', IsoRectangleShape); 380 381 // Cube Shape, supports size style 382 function WaypointShape() 383 { 384 mxCylinder.call(this); 385 }; 386 mxUtils.extend(WaypointShape, mxCylinder); 387 WaypointShape.prototype.size = 6; 388 389 WaypointShape.prototype.paintVertexShape = function(c, x, y, w, h) 390 { 391 c.setFillColor(this.stroke); 392 var s = Math.max(0, parseFloat(mxUtils.getValue(this.style, 'size', this.size)) - 2) + 2 * this.strokewidth; 393 c.ellipse(x + (w - s) * 0.5, y + (h - s) * 0.5, s, s); 394 c.fill(); 395 396 c.setFillColor(mxConstants.NONE); 397 c.rect(x, y, w, h); 398 c.fill(); 399 }; 400 401 mxCellRenderer.registerShape('waypoint', WaypointShape); 402 403 // Cube Shape, supports size style 404 function IsoRectangleShape() 405 { 406 mxActor.call(this); 407 }; 408 mxUtils.extend(IsoRectangleShape, mxActor); 409 IsoRectangleShape.prototype.size = 20; 410 IsoRectangleShape.prototype.redrawPath = function(path, x, y, w, h) 411 { 412 var m = Math.min(w, h / tan30); 413 414 path.translate((w - m) / 2, (h - m) / 2 + m / 4); 415 path.moveTo(0, 0.25 * m); 416 path.lineTo(0.5 * m, m * tan30Dx); 417 path.lineTo(m, 0.25 * m); 418 path.lineTo(0.5 * m, (0.5 - tan30Dx) * m); 419 path.lineTo(0, 0.25 * m); 420 path.close(); 421 path.end(); 422 }; 423 424 mxCellRenderer.registerShape('isoRectangle', IsoRectangleShape); 425 426 // Cube Shape, supports size style 427 function IsoCubeShape() 428 { 429 mxCylinder.call(this); 430 }; 431 mxUtils.extend(IsoCubeShape, mxCylinder); 432 IsoCubeShape.prototype.size = 20; 433 IsoCubeShape.prototype.redrawPath = function(path, x, y, w, h, isForeground) 434 { 435 var m = Math.min(w, h / (0.5 + tan30)); 436 437 if (isForeground) 438 { 439 path.moveTo(0, 0.25 * m); 440 path.lineTo(0.5 * m, (0.5 - tan30Dx) * m); 441 path.lineTo(m, 0.25 * m); 442 path.moveTo(0.5 * m, (0.5 - tan30Dx) * m); 443 path.lineTo(0.5 * m, (1 - tan30Dx) * m); 444 path.end(); 445 } 446 else 447 { 448 path.translate((w - m) / 2, (h - m) / 2); 449 path.moveTo(0, 0.25 * m); 450 path.lineTo(0.5 * m, m * tan30Dx); 451 path.lineTo(m, 0.25 * m); 452 path.lineTo(m, 0.75 * m); 453 path.lineTo(0.5 * m, (1 - tan30Dx) * m); 454 path.lineTo(0, 0.75 * m); 455 path.close(); 456 path.end(); 457 } 458 }; 459 460 mxCellRenderer.registerShape('isoCube', IsoCubeShape); 461 462 // DataStore Shape, supports size style 463 function DataStoreShape() 464 { 465 mxCylinder.call(this); 466 }; 467 mxUtils.extend(DataStoreShape, mxCylinder); 468 469 DataStoreShape.prototype.redrawPath = function(c, x, y, w, h, isForeground) 470 { 471 var dy = Math.min(h / 2, Math.round(h / 8) + this.strokewidth - 1); 472 473 if ((isForeground && this.fill != null) || (!isForeground && this.fill == null)) 474 { 475 c.moveTo(0, dy); 476 c.curveTo(0, 2 * dy, w, 2 * dy, w, dy); 477 478 // Needs separate shapes for correct hit-detection 479 if (!isForeground) 480 { 481 c.stroke(); 482 c.begin(); 483 } 484 485 c.translate(0, dy / 2); 486 c.moveTo(0, dy); 487 c.curveTo(0, 2 * dy, w, 2 * dy, w, dy); 488 489 // Needs separate shapes for correct hit-detection 490 if (!isForeground) 491 { 492 c.stroke(); 493 c.begin(); 494 } 495 496 c.translate(0, dy / 2); 497 c.moveTo(0, dy); 498 c.curveTo(0, 2 * dy, w, 2 * dy, w, dy); 499 500 // Needs separate shapes for correct hit-detection 501 if (!isForeground) 502 { 503 c.stroke(); 504 c.begin(); 505 } 506 507 c.translate(0, -dy); 508 } 509 510 if (!isForeground) 511 { 512 c.moveTo(0, dy); 513 c.curveTo(0, -dy / 3, w, -dy / 3, w, dy); 514 c.lineTo(w, h - dy); 515 c.curveTo(w, h + dy / 3, 0, h + dy / 3, 0, h - dy); 516 c.close(); 517 } 518 }; 519 DataStoreShape.prototype.getLabelMargins = function(rect) 520 { 521 return new mxRectangle(0, 2.5 * Math.min(rect.height / 2, 522 Math.round(rect.height / 8) + this.strokewidth - 1), 0, 0); 523 } 524 525 mxCellRenderer.registerShape('datastore', DataStoreShape); 526 527 // Note Shape, supports size style 528 function NoteShape() 529 { 530 mxCylinder.call(this); 531 }; 532 mxUtils.extend(NoteShape, mxCylinder); 533 NoteShape.prototype.size = 30; 534 NoteShape.prototype.darkOpacity = 0; 535 536 NoteShape.prototype.paintVertexShape = function(c, x, y, w, h) 537 { 538 var s = Math.max(0, Math.min(w, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size))))); 539 var op = Math.max(-1, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'darkOpacity', this.darkOpacity)))); 540 c.translate(x, y); 541 542 c.begin(); 543 c.moveTo(0, 0); 544 c.lineTo(w - s, 0); 545 c.lineTo(w, s); 546 c.lineTo(w, h); 547 c.lineTo(0, h); 548 c.lineTo(0, 0); 549 c.close(); 550 c.end(); 551 c.fillAndStroke(); 552 553 if (!this.outline) 554 { 555 c.setShadow(false); 556 557 if (op != 0) 558 { 559 c.setFillAlpha(Math.abs(op)); 560 c.setFillColor((op < 0) ? '#FFFFFF' : '#000000'); 561 c.begin(); 562 c.moveTo(w - s, 0); 563 c.lineTo(w - s, s); 564 c.lineTo(w, s); 565 c.close(); 566 c.fill(); 567 } 568 569 c.begin(); 570 c.moveTo(w - s, 0); 571 c.lineTo(w - s, s); 572 c.lineTo(w, s); 573 c.end(); 574 c.stroke(); 575 } 576 }; 577 578 mxCellRenderer.registerShape('note', NoteShape); 579 580 // Note Shape, supports size style 581 function NoteShape2() 582 { 583 NoteShape.call(this); 584 }; 585 mxUtils.extend(NoteShape2, NoteShape); 586 587 mxCellRenderer.registerShape('note2', NoteShape2); 588 589 NoteShape2.prototype.getLabelMargins = function(rect) 590 { 591 if (mxUtils.getValue(this.style, 'boundedLbl', false)) 592 { 593 var size = mxUtils.getValue(this.style, 'size', 15); 594 595 return new mxRectangle(0, Math.min(rect.height * this.scale, size * this.scale), 0, 0); 596 } 597 598 return null; 599 }; 600 601 // Flexible cube Shape 602 function IsoCubeShape2() 603 { 604 mxShape.call(this); 605 }; 606 mxUtils.extend(IsoCubeShape2, mxShape); 607 IsoCubeShape2.prototype.isoAngle = 15; 608 609 IsoCubeShape2.prototype.paintVertexShape = function(c, x, y, w, h) 610 { 611 var isoAngle = Math.max(0.01, Math.min(94, parseFloat(mxUtils.getValue(this.style, 'isoAngle', this.isoAngle)))) * Math.PI / 200 ; 612 var isoH = Math.min(w * Math.tan(isoAngle), h * 0.5); 613 614 c.translate(x,y); 615 616 c.begin(); 617 c.moveTo(w * 0.5, 0); 618 c.lineTo(w, isoH); 619 c.lineTo(w, h - isoH); 620 c.lineTo(w * 0.5, h); 621 c.lineTo(0, h - isoH); 622 c.lineTo(0, isoH); 623 c.close(); 624 c.fillAndStroke(); 625 626 c.setShadow(false); 627 628 c.begin(); 629 c.moveTo(0, isoH); 630 c.lineTo(w * 0.5, 2 * isoH); 631 c.lineTo(w, isoH); 632 c.moveTo(w * 0.5, 2 * isoH); 633 c.lineTo(w * 0.5, h); 634 c.stroke(); 635 }; 636 637 mxCellRenderer.registerShape('isoCube2', IsoCubeShape2); 638 639 // (LEGACY) Flexible cylinder Shape 640 function CylinderShape() 641 { 642 mxShape.call(this); 643 }; 644 645 mxUtils.extend(CylinderShape, mxShape); 646 647 CylinderShape.prototype.size = 15; 648 649 CylinderShape.prototype.paintVertexShape = function(c, x, y, w, h) 650 { 651 var size = Math.max(0, Math.min(h * 0.5, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); 652 653 c.translate(x,y); 654 655 if (size == 0) 656 { 657 c.rect(0, 0, w, h); 658 c.fillAndStroke(); 659 } 660 else 661 { 662 c.begin(); 663 c.moveTo(0, size); 664 c.arcTo(w * 0.5, size, 0, 0, 1, w * 0.5, 0); 665 c.arcTo(w * 0.5, size, 0, 0, 1, w, size); 666 c.lineTo(w, h - size); 667 c.arcTo(w * 0.5, size, 0, 0, 1, w * 0.5, h); 668 c.arcTo(w * 0.5, size, 0, 0, 1, 0, h - size); 669 c.close(); 670 c.fillAndStroke(); 671 672 c.setShadow(false); 673 674 c.begin(); 675 c.moveTo(w, size); 676 c.arcTo(w * 0.5, size, 0, 0, 1, w * 0.5, 2 * size); 677 c.arcTo(w * 0.5, size, 0, 0, 1, 0, size); 678 c.stroke(); 679 } 680 }; 681 682 mxCellRenderer.registerShape('cylinder2', CylinderShape); 683 684 // Flexible cylinder3 Shape with offset label 685 function CylinderShape3(bounds, fill, stroke, strokewidth) 686 { 687 mxShape.call(this); 688 this.bounds = bounds; 689 this.fill = fill; 690 this.stroke = stroke; 691 this.strokewidth = (strokewidth != null) ? strokewidth : 1; 692 }; 693 694 mxUtils.extend(CylinderShape3, mxCylinder); 695 696 CylinderShape3.prototype.size = 15; 697 698 CylinderShape3.prototype.paintVertexShape = function(c, x, y, w, h) 699 { 700 var size = Math.max(0, Math.min(h * 0.5, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); 701 var lid = mxUtils.getValue(this.style, 'lid', true); 702 703 c.translate(x,y); 704 705 if (size == 0) 706 { 707 c.rect(0, 0, w, h); 708 c.fillAndStroke(); 709 } 710 else 711 { 712 c.begin(); 713 714 if (lid) 715 { 716 c.moveTo(0, size); 717 c.arcTo(w * 0.5, size, 0, 0, 1, w * 0.5, 0); 718 c.arcTo(w * 0.5, size, 0, 0, 1, w, size); 719 } 720 else 721 { 722 c.moveTo(0, 0); 723 c.arcTo(w * 0.5, size, 0, 0, 0, w * 0.5, size); 724 c.arcTo(w * 0.5, size, 0, 0, 0, w, 0); 725 } 726 727 c.lineTo(w, h - size); 728 c.arcTo(w * 0.5, size, 0, 0, 1, w * 0.5, h); 729 c.arcTo(w * 0.5, size, 0, 0, 1, 0, h - size); 730 c.close(); 731 c.fillAndStroke(); 732 733 c.setShadow(false); 734 735 if (lid) 736 { 737 c.begin(); 738 c.moveTo(w, size); 739 c.arcTo(w * 0.5, size, 0, 0, 1, w * 0.5, 2 * size); 740 c.arcTo(w * 0.5, size, 0, 0, 1, 0, size); 741 c.stroke(); 742 } 743 } 744 }; 745 746 mxCellRenderer.registerShape('cylinder3', CylinderShape3); 747 748 // Switch Shape, supports size style 749 function SwitchShape() 750 { 751 mxActor.call(this); 752 }; 753 mxUtils.extend(SwitchShape, mxActor); 754 SwitchShape.prototype.redrawPath = function(c, x, y, w, h) 755 { 756 var curve = 0.5; 757 c.moveTo(0, 0); 758 c.quadTo(w / 2, h * curve, w, 0); 759 c.quadTo(w * (1 - curve), h / 2, w, h); 760 c.quadTo(w / 2, h * (1 - curve), 0, h); 761 c.quadTo(w * curve, h / 2, 0, 0); 762 c.end(); 763 }; 764 765 mxCellRenderer.registerShape('switch', SwitchShape); 766 767 // Folder Shape, supports tabWidth, tabHeight styles 768 function FolderShape() 769 { 770 mxCylinder.call(this); 771 }; 772 mxUtils.extend(FolderShape, mxCylinder); 773 FolderShape.prototype.tabWidth = 60; 774 FolderShape.prototype.tabHeight = 20; 775 FolderShape.prototype.tabPosition = 'right'; 776 FolderShape.prototype.arcSize = 0.1; 777 778 FolderShape.prototype.paintVertexShape = function(c, x, y, w, h) 779 { 780 c.translate(x, y); 781 782 var dx = Math.max(0, Math.min(w, parseFloat(mxUtils.getValue(this.style, 'tabWidth', this.tabWidth)))); 783 var dy = Math.max(0, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'tabHeight', this.tabHeight)))); 784 var tp = mxUtils.getValue(this.style, 'tabPosition', this.tabPosition); 785 var rounded = mxUtils.getValue(this.style, 'rounded', false); 786 var absArcSize = mxUtils.getValue(this.style, 'absoluteArcSize', false); 787 var arcSize = parseFloat(mxUtils.getValue(this.style, 'arcSize', this.arcSize)); 788 789 if (!absArcSize) 790 { 791 arcSize = Math.min(w, h) * arcSize; 792 } 793 794 arcSize = Math.min(arcSize, w * 0.5, (h - dy) * 0.5); 795 796 dx = Math.max(dx, arcSize); 797 dx = Math.min(w - arcSize, dx); 798 799 if (!rounded) 800 { 801 arcSize = 0; 802 } 803 804 c.begin(); 805 806 if (tp == 'left') 807 { 808 c.moveTo(Math.max(arcSize, 0), dy); 809 c.lineTo(Math.max(arcSize, 0), 0); 810 c.lineTo(dx, 0); 811 c.lineTo(dx, dy); 812 } 813 // Right is default 814 else 815 { 816 c.moveTo(w - dx, dy); 817 c.lineTo(w - dx, 0); 818 c.lineTo(w - Math.max(arcSize, 0), 0); 819 c.lineTo(w - Math.max(arcSize, 0), dy); 820 } 821 822 if (rounded) 823 { 824 c.moveTo(0, arcSize + dy); 825 c.arcTo(arcSize, arcSize, 0, 0, 1, arcSize, dy); 826 c.lineTo(w - arcSize, dy); 827 c.arcTo(arcSize, arcSize, 0, 0, 1, w, arcSize + dy); 828 c.lineTo(w, h - arcSize); 829 c.arcTo(arcSize, arcSize, 0, 0, 1, w - arcSize, h); 830 c.lineTo(arcSize, h); 831 c.arcTo(arcSize, arcSize, 0, 0, 1, 0, h - arcSize); 832 } 833 else 834 { 835 c.moveTo(0, dy); 836 c.lineTo(w, dy); 837 c.lineTo(w, h); 838 c.lineTo(0, h); 839 } 840 841 c.close(); 842 c.fillAndStroke(); 843 844 c.setShadow(false); 845 846 var sym = mxUtils.getValue(this.style, 'folderSymbol', null); 847 848 if (sym == 'triangle') 849 { 850 c.begin(); 851 c.moveTo(w - 30, dy + 20); 852 c.lineTo(w - 20, dy + 10); 853 c.lineTo(w - 10, dy + 20); 854 c.close(); 855 c.stroke(); 856 } 857 }; 858 859 mxCellRenderer.registerShape('folder', FolderShape); 860 861 FolderShape.prototype.getLabelMargins = function(rect) 862 { 863 if (mxUtils.getValue(this.style, 'boundedLbl', false)) 864 { 865 var sizeY = mxUtils.getValue(this.style, 'tabHeight', 15) * this.scale; 866 867 if (mxUtils.getValue(this.style, 'labelInHeader', false)) 868 { 869 var sizeX = mxUtils.getValue(this.style, 'tabWidth', 15) * this.scale; 870 var sizeY = mxUtils.getValue(this.style, 'tabHeight', 15) * this.scale; 871 var rounded = mxUtils.getValue(this.style, 'rounded', false); 872 var absArcSize = mxUtils.getValue(this.style, 'absoluteArcSize', false); 873 var arcSize = parseFloat(mxUtils.getValue(this.style, 'arcSize', this.arcSize)); 874 875 if (!absArcSize) 876 { 877 arcSize = Math.min(rect.width, rect.height) * arcSize; 878 } 879 880 arcSize = Math.min(arcSize, rect.width * 0.5, (rect.height - sizeY) * 0.5); 881 882 if (!rounded) 883 { 884 arcSize = 0; 885 } 886 887 if (mxUtils.getValue(this.style, 'tabPosition', this.tabPosition) == 'left') 888 { 889 return new mxRectangle(arcSize, 0, Math.min(rect.width, rect.width - sizeX), Math.min(rect.height, rect.height - sizeY)); 890 } 891 else 892 { 893 return new mxRectangle(Math.min(rect.width, rect.width - sizeX), 0, arcSize, Math.min(rect.height, rect.height - sizeY)); 894 } 895 } 896 else 897 { 898 return new mxRectangle(0, Math.min(rect.height, sizeY), 0, 0); 899 } 900 } 901 902 return null; 903 }; 904 905 //********************************************************************************************************************************************************** 906 //UML State shape 907 //********************************************************************************************************************************************************** 908 function UMLStateShape() 909 { 910 mxCylinder.call(this); 911 }; 912 mxUtils.extend(UMLStateShape, mxCylinder); 913 UMLStateShape.prototype.arcSize = 0.1; 914 915 UMLStateShape.prototype.paintVertexShape = function(c, x, y, w, h) 916 { 917 c.translate(x, y); 918 919 var rounded = mxUtils.getValue(this.style, 'rounded', false); 920 var absArcSize = mxUtils.getValue(this.style, 'absoluteArcSize', false); 921 var arcSize = parseFloat(mxUtils.getValue(this.style, 'arcSize', this.arcSize)); 922 var connPoint = mxUtils.getValue(this.style, 'umlStateConnection', null); 923 924 if (!absArcSize) 925 { 926 arcSize = Math.min(w, h) * arcSize; 927 } 928 929 arcSize = Math.min(arcSize, w * 0.5, h * 0.5); 930 931 if (!rounded) 932 { 933 arcSize = 0; 934 } 935 936 var dx = 0; 937 938 if (connPoint != null) 939 { 940 dx = 10; 941 } 942 943 c.begin(); 944 c.moveTo(dx, arcSize); 945 c.arcTo(arcSize, arcSize, 0, 0, 1, dx + arcSize, 0); 946 c.lineTo(w - arcSize, 0); 947 c.arcTo(arcSize, arcSize, 0, 0, 1, w, arcSize); 948 c.lineTo(w, h - arcSize); 949 c.arcTo(arcSize, arcSize, 0, 0, 1, w - arcSize, h); 950 c.lineTo(dx + arcSize, h); 951 c.arcTo(arcSize, arcSize, 0, 0, 1, dx, h - arcSize); 952 c.close(); 953 c.fillAndStroke(); 954 955 c.setShadow(false); 956 957 var sym = mxUtils.getValue(this.style, 'umlStateSymbol', null); 958 959 if (sym == 'collapseState') 960 { 961 c.roundrect(w - 40, h - 20, 10, 10, 3, 3); 962 c.stroke(); 963 c.roundrect(w - 20, h - 20, 10, 10, 3, 3); 964 c.stroke(); 965 c.begin(); 966 c.moveTo(w - 30, h - 15); 967 c.lineTo(w - 20, h - 15); 968 c.stroke(); 969 } 970 971 if (connPoint == 'connPointRefEntry') 972 { 973 c.ellipse(0, h * 0.5 - 10, 20, 20); 974 c.fillAndStroke(); 975 } 976 else if (connPoint == 'connPointRefExit') 977 { 978 c.ellipse(0, h * 0.5 - 10, 20, 20); 979 c.fillAndStroke(); 980 981 c.begin(); 982 c.moveTo(5, h * 0.5 - 5); 983 c.lineTo(15, h * 0.5 + 5); 984 c.moveTo(15, h * 0.5 - 5); 985 c.lineTo(5, h * 0.5 + 5); 986 c.stroke(); 987 } 988 }; 989 990 UMLStateShape.prototype.getLabelMargins = function(rect) 991 { 992 if (mxUtils.getValue(this.style, 'boundedLbl', false)) 993 { 994 var connPoint = mxUtils.getValue(this.style, 'umlStateConnection', null); 995 996 if (connPoint != null) 997 { 998 return new mxRectangle(10 * this.scale, 0, 0, 0); 999 } 1000 } 1001 1002 return null; 1003 }; 1004 1005 mxCellRenderer.registerShape('umlState', UMLStateShape); 1006 1007 // Card shape 1008 function CardShape() 1009 { 1010 mxActor.call(this); 1011 }; 1012 mxUtils.extend(CardShape, mxActor); 1013 CardShape.prototype.size = 30; 1014 CardShape.prototype.isRoundable = function() 1015 { 1016 return true; 1017 }; 1018 CardShape.prototype.redrawPath = function(c, x, y, w, h) 1019 { 1020 var s = Math.max(0, Math.min(w, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size))))); 1021 var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2; 1022 this.addPoints(c, [new mxPoint(s, 0), new mxPoint(w, 0), new mxPoint(w, h), new mxPoint(0, h), new mxPoint(0, s)], 1023 this.isRounded, arcSize, true); 1024 c.end(); 1025 }; 1026 1027 mxCellRenderer.registerShape('card', CardShape); 1028 1029 // Tape shape 1030 function TapeShape() 1031 { 1032 mxActor.call(this); 1033 }; 1034 mxUtils.extend(TapeShape, mxActor); 1035 TapeShape.prototype.size = 0.4; 1036 TapeShape.prototype.redrawPath = function(c, x, y, w, h) 1037 { 1038 var dy = h * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); 1039 var fy = 1.4; 1040 1041 c.moveTo(0, dy / 2); 1042 c.quadTo(w / 4, dy * fy, w / 2, dy / 2); 1043 c.quadTo(w * 3 / 4, dy * (1 - fy), w, dy / 2); 1044 c.lineTo(w, h - dy / 2); 1045 c.quadTo(w * 3 / 4, h - dy * fy, w / 2, h - dy / 2); 1046 c.quadTo(w / 4, h - dy * (1 - fy), 0, h - dy / 2); 1047 c.lineTo(0, dy / 2); 1048 c.close(); 1049 c.end(); 1050 }; 1051 1052 TapeShape.prototype.getLabelBounds = function(rect) 1053 { 1054 if (mxUtils.getValue(this.style, 'boundedLbl', false)) 1055 { 1056 var size = mxUtils.getValue(this.style, 'size', this.size); 1057 var w = rect.width; 1058 var h = rect.height; 1059 1060 if (this.direction == null || 1061 this.direction == mxConstants.DIRECTION_EAST || 1062 this.direction == mxConstants.DIRECTION_WEST) 1063 { 1064 var dy = h * size; 1065 1066 return new mxRectangle(rect.x, rect.y + dy, w, h - 2 * dy); 1067 } 1068 else 1069 { 1070 var dx = w * size; 1071 1072 return new mxRectangle(rect.x + dx, rect.y, w - 2 * dx, h); 1073 } 1074 } 1075 1076 return rect; 1077 }; 1078 1079 mxCellRenderer.registerShape('tape', TapeShape); 1080 1081 // Document shape 1082 function DocumentShape() 1083 { 1084 mxActor.call(this); 1085 }; 1086 mxUtils.extend(DocumentShape, mxActor); 1087 DocumentShape.prototype.size = 0.3; 1088 DocumentShape.prototype.getLabelMargins = function(rect) 1089 { 1090 if (mxUtils.getValue(this.style, 'boundedLbl', false)) 1091 { 1092 return new mxRectangle(0, 0, 0, parseFloat(mxUtils.getValue( 1093 this.style, 'size', this.size)) * rect.height); 1094 } 1095 1096 return null; 1097 }; 1098 DocumentShape.prototype.redrawPath = function(c, x, y, w, h) 1099 { 1100 var dy = h * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); 1101 var fy = 1.4; 1102 1103 c.moveTo(0, 0); 1104 c.lineTo(w, 0); 1105 c.lineTo(w, h - dy / 2); 1106 c.quadTo(w * 3 / 4, h - dy * fy, w / 2, h - dy / 2); 1107 c.quadTo(w / 4, h - dy * (1 - fy), 0, h - dy / 2); 1108 c.lineTo(0, dy / 2); 1109 c.close(); 1110 c.end(); 1111 }; 1112 1113 mxCellRenderer.registerShape('document', DocumentShape); 1114 1115 var cylinderGetCylinderSize = mxCylinder.prototype.getCylinderSize; 1116 1117 mxCylinder.prototype.getCylinderSize = function(x, y, w, h) 1118 { 1119 var size = mxUtils.getValue(this.style, 'size'); 1120 1121 if (size != null) 1122 { 1123 return h * Math.max(0, Math.min(1, size)); 1124 } 1125 else 1126 { 1127 return cylinderGetCylinderSize.apply(this, arguments); 1128 } 1129 }; 1130 1131 mxCylinder.prototype.getLabelMargins = function(rect) 1132 { 1133 if (mxUtils.getValue(this.style, 'boundedLbl', false)) 1134 { 1135 var size = mxUtils.getValue(this.style, 'size', 0.15) * 2; 1136 1137 return new mxRectangle(0, Math.min(this.maxHeight * this.scale, rect.height * size), 0, 0); 1138 } 1139 1140 return null; 1141 }; 1142 1143 CylinderShape3.prototype.getLabelMargins = function(rect) 1144 { 1145 if (mxUtils.getValue(this.style, 'boundedLbl', false)) 1146 { 1147 var size = mxUtils.getValue(this.style, 'size', 15); 1148 1149 if (!mxUtils.getValue(this.style, 'lid', true)) 1150 { 1151 size /= 2; 1152 } 1153 1154 return new mxRectangle(0, Math.min(rect.height * this.scale, size * 2 * this.scale), 0, Math.max(0, size * 0.3 * this.scale)); 1155 } 1156 1157 return null; 1158 }; 1159 1160 FolderShape.prototype.getLabelMargins = function(rect) 1161 { 1162 if (mxUtils.getValue(this.style, 'boundedLbl', false)) 1163 { 1164 var sizeY = mxUtils.getValue(this.style, 'tabHeight', 15) * this.scale; 1165 1166 if (mxUtils.getValue(this.style, 'labelInHeader', false)) 1167 { 1168 var sizeX = mxUtils.getValue(this.style, 'tabWidth', 15) * this.scale; 1169 var sizeY = mxUtils.getValue(this.style, 'tabHeight', 15) * this.scale; 1170 var rounded = mxUtils.getValue(this.style, 'rounded', false); 1171 var absArcSize = mxUtils.getValue(this.style, 'absoluteArcSize', false); 1172 var arcSize = parseFloat(mxUtils.getValue(this.style, 'arcSize', this.arcSize)); 1173 1174 if (!absArcSize) 1175 { 1176 arcSize = Math.min(rect.width, rect.height) * arcSize; 1177 } 1178 1179 arcSize = Math.min(arcSize, rect.width * 0.5, (rect.height - sizeY) * 0.5); 1180 1181 if (!rounded) 1182 { 1183 arcSize = 0; 1184 } 1185 1186 if (mxUtils.getValue(this.style, 'tabPosition', this.tabPosition) == 'left') 1187 { 1188 return new mxRectangle(arcSize, 0, Math.min(rect.width, rect.width - sizeX), Math.min(rect.height, rect.height - sizeY)); 1189 } 1190 else 1191 { 1192 return new mxRectangle(Math.min(rect.width, rect.width - sizeX), 0, arcSize, Math.min(rect.height, rect.height - sizeY)); 1193 } 1194 } 1195 else 1196 { 1197 return new mxRectangle(0, Math.min(rect.height, sizeY), 0, 0); 1198 } 1199 } 1200 1201 return null; 1202 }; 1203 1204 UMLStateShape.prototype.getLabelMargins = function(rect) 1205 { 1206 if (mxUtils.getValue(this.style, 'boundedLbl', false)) 1207 { 1208 var connPoint = mxUtils.getValue(this.style, 'umlStateConnection', null); 1209 1210 if (connPoint != null) 1211 { 1212 return new mxRectangle(10 * this.scale, 0, 0, 0); 1213 } 1214 } 1215 1216 return null; 1217 }; 1218 1219 NoteShape2.prototype.getLabelMargins = function(rect) 1220 { 1221 if (mxUtils.getValue(this.style, 'boundedLbl', false)) 1222 { 1223 var size = mxUtils.getValue(this.style, 'size', 15); 1224 1225 return new mxRectangle(0, Math.min(rect.height * this.scale, size * this.scale), 0, Math.max(0, size * this.scale)); 1226 } 1227 1228 return null; 1229 }; 1230 1231 // Parallelogram shape 1232 function ParallelogramShape() 1233 { 1234 mxActor.call(this); 1235 }; 1236 mxUtils.extend(ParallelogramShape, mxActor); 1237 ParallelogramShape.prototype.size = 0.2; 1238 ParallelogramShape.prototype.fixedSize = 20; 1239 ParallelogramShape.prototype.isRoundable = function() 1240 { 1241 return true; 1242 }; 1243 ParallelogramShape.prototype.redrawPath = function(c, x, y, w, h) 1244 { 1245 var fixed = mxUtils.getValue(this.style, 'fixedSize', '0') != '0'; 1246 1247 var dx = (fixed) ? Math.max(0, Math.min(w, parseFloat(mxUtils.getValue(this.style, 'size', this.fixedSize)))) : w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); 1248 var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2; 1249 this.addPoints(c, [new mxPoint(0, h), new mxPoint(dx, 0), new mxPoint(w, 0), new mxPoint(w - dx, h)], 1250 this.isRounded, arcSize, true); 1251 c.end(); 1252 }; 1253 1254 mxCellRenderer.registerShape('parallelogram', ParallelogramShape); 1255 1256 // Trapezoid shape 1257 function TrapezoidShape() 1258 { 1259 mxActor.call(this); 1260 }; 1261 mxUtils.extend(TrapezoidShape, mxActor); 1262 TrapezoidShape.prototype.size = 0.2; 1263 TrapezoidShape.prototype.fixedSize = 20; 1264 TrapezoidShape.prototype.isRoundable = function() 1265 { 1266 return true; 1267 }; 1268 TrapezoidShape.prototype.redrawPath = function(c, x, y, w, h) 1269 { 1270 1271 var fixed = mxUtils.getValue(this.style, 'fixedSize', '0') != '0'; 1272 1273 var dx = (fixed) ? Math.max(0, Math.min(w * 0.5, parseFloat(mxUtils.getValue(this.style, 'size', this.fixedSize)))) : w * Math.max(0, Math.min(0.5, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); 1274 var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2; 1275 this.addPoints(c, [new mxPoint(0, h), new mxPoint(dx, 0), new mxPoint(w - dx, 0), new mxPoint(w, h)], 1276 this.isRounded, arcSize, true); 1277 }; 1278 1279 mxCellRenderer.registerShape('trapezoid', TrapezoidShape); 1280 1281 // Curly Bracket shape 1282 function CurlyBracketShape() 1283 { 1284 mxActor.call(this); 1285 }; 1286 mxUtils.extend(CurlyBracketShape, mxActor); 1287 CurlyBracketShape.prototype.size = 0.5; 1288 CurlyBracketShape.prototype.redrawPath = function(c, x, y, w, h) 1289 { 1290 c.setFillColor(null); 1291 var s = w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); 1292 var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2; 1293 this.addPoints(c, [new mxPoint(w, 0), new mxPoint(s, 0), new mxPoint(s, h / 2), 1294 new mxPoint(0, h / 2), new mxPoint(s, h / 2), new mxPoint(s, h), 1295 new mxPoint(w, h)], this.isRounded, arcSize, false); 1296 c.end(); 1297 }; 1298 1299 mxCellRenderer.registerShape('curlyBracket', CurlyBracketShape); 1300 1301 // Parallel marker shape 1302 function ParallelMarkerShape() 1303 { 1304 mxActor.call(this); 1305 }; 1306 mxUtils.extend(ParallelMarkerShape, mxActor); 1307 ParallelMarkerShape.prototype.redrawPath = function(c, x, y, w, h) 1308 { 1309 c.setStrokeWidth(1); 1310 c.setFillColor(this.stroke); 1311 var w2 = w / 5; 1312 c.rect(0, 0, w2, h); 1313 c.fillAndStroke(); 1314 c.rect(2 * w2, 0, w2, h); 1315 c.fillAndStroke(); 1316 c.rect(4 * w2, 0, w2, h); 1317 c.fillAndStroke(); 1318 }; 1319 1320 mxCellRenderer.registerShape('parallelMarker', ParallelMarkerShape); 1321 1322 /** 1323 * Adds handJiggle style (jiggle=n sets jiggle) 1324 */ 1325 function HandJiggle(canvas, defaultVariation) 1326 { 1327 this.canvas = canvas; 1328 1329 // Avoids "spikes" in the output 1330 this.canvas.setLineJoin('round'); 1331 this.canvas.setLineCap('round'); 1332 1333 this.defaultVariation = defaultVariation; 1334 1335 this.originalLineTo = this.canvas.lineTo; 1336 this.canvas.lineTo = mxUtils.bind(this, HandJiggle.prototype.lineTo); 1337 1338 this.originalMoveTo = this.canvas.moveTo; 1339 this.canvas.moveTo = mxUtils.bind(this, HandJiggle.prototype.moveTo); 1340 1341 this.originalClose = this.canvas.close; 1342 this.canvas.close = mxUtils.bind(this, HandJiggle.prototype.close); 1343 1344 this.originalQuadTo = this.canvas.quadTo; 1345 this.canvas.quadTo = mxUtils.bind(this, HandJiggle.prototype.quadTo); 1346 1347 this.originalCurveTo = this.canvas.curveTo; 1348 this.canvas.curveTo = mxUtils.bind(this, HandJiggle.prototype.curveTo); 1349 1350 this.originalArcTo = this.canvas.arcTo; 1351 this.canvas.arcTo = mxUtils.bind(this, HandJiggle.prototype.arcTo); 1352 }; 1353 1354 HandJiggle.prototype.moveTo = function(endX, endY) 1355 { 1356 this.originalMoveTo.apply(this.canvas, arguments); 1357 this.lastX = endX; 1358 this.lastY = endY; 1359 this.firstX = endX; 1360 this.firstY = endY; 1361 }; 1362 1363 HandJiggle.prototype.close = function() 1364 { 1365 if (this.firstX != null && this.firstY != null) 1366 { 1367 this.lineTo(this.firstX, this.firstY); 1368 this.originalClose.apply(this.canvas, arguments); 1369 } 1370 1371 this.originalClose.apply(this.canvas, arguments); 1372 }; 1373 1374 HandJiggle.prototype.quadTo = function(x1, y1, x2, y2) 1375 { 1376 this.originalQuadTo.apply(this.canvas, arguments); 1377 this.lastX = x2; 1378 this.lastY = y2; 1379 }; 1380 1381 HandJiggle.prototype.curveTo = function(x1, y1, x2, y2, x3, y3) 1382 { 1383 this.originalCurveTo.apply(this.canvas, arguments); 1384 this.lastX = x3; 1385 this.lastY = y3; 1386 }; 1387 1388 HandJiggle.prototype.arcTo = function(rx, ry, angle, largeArcFlag, sweepFlag, x, y) 1389 { 1390 this.originalArcTo.apply(this.canvas, arguments); 1391 this.lastX = x; 1392 this.lastY = y; 1393 }; 1394 1395 HandJiggle.prototype.lineTo = function(endX, endY) 1396 { 1397 // LATER: Check why this.canvas.lastX cannot be used 1398 if (this.lastX != null && this.lastY != null) 1399 { 1400 var dx = Math.abs(endX - this.lastX); 1401 var dy = Math.abs(endY - this.lastY); 1402 var dist = Math.sqrt(dx * dx + dy * dy); 1403 1404 if (dist < 2) 1405 { 1406 this.originalLineTo.apply(this.canvas, arguments); 1407 this.lastX = endX; 1408 this.lastY = endY; 1409 1410 return; 1411 } 1412 1413 var segs = Math.round(dist / 10); 1414 var variation = this.defaultVariation; 1415 1416 if (segs < 5) 1417 { 1418 segs = 5; 1419 variation /= 3; 1420 } 1421 1422 function sign(x) 1423 { 1424 return typeof x === 'number' ? x ? x < 0 ? -1 : 1 : x === x ? 0 : NaN : NaN; 1425 } 1426 1427 var stepX = sign(endX - this.lastX) * dx / segs; 1428 var stepY = sign(endY - this.lastY) * dy / segs; 1429 1430 var fx = dx / dist; 1431 var fy = dy / dist; 1432 1433 for (var s = 0; s < segs; s++) 1434 { 1435 var x = stepX * s + this.lastX; 1436 var y = stepY * s + this.lastY; 1437 1438 var offset = (Math.random() - 0.5) * variation; 1439 this.originalLineTo.call(this.canvas, x - offset * fy, y - offset * fx); 1440 } 1441 1442 this.originalLineTo.call(this.canvas, endX, endY); 1443 this.lastX = endX; 1444 this.lastY = endY; 1445 } 1446 else 1447 { 1448 this.originalLineTo.apply(this.canvas, arguments); 1449 this.lastX = endX; 1450 this.lastY = endY; 1451 } 1452 }; 1453 1454 HandJiggle.prototype.destroy = function() 1455 { 1456 this.canvas.lineTo = this.originalLineTo; 1457 this.canvas.moveTo = this.originalMoveTo; 1458 this.canvas.close = this.originalClose; 1459 this.canvas.quadTo = this.originalQuadTo; 1460 this.canvas.curveTo = this.originalCurveTo; 1461 this.canvas.arcTo = this.originalArcTo; 1462 }; 1463 1464 // Installs hand jiggle for comic and sketch style 1465 mxShape.prototype.defaultJiggle = 1.5; 1466 1467 var shapeBeforePaint = mxShape.prototype.beforePaint; 1468 mxShape.prototype.beforePaint = function(c) 1469 { 1470 shapeBeforePaint.apply(this, arguments); 1471 1472 if (c.handJiggle == null) 1473 { 1474 c.handJiggle = this.createHandJiggle(c); 1475 } 1476 }; 1477 1478 var shapeAfterPaint = mxShape.prototype.afterPaint; 1479 mxShape.prototype.afterPaint = function(c) 1480 { 1481 shapeAfterPaint.apply(this, arguments); 1482 1483 if (c.handJiggle != null) 1484 { 1485 c.handJiggle.destroy(); 1486 delete c.handJiggle; 1487 } 1488 }; 1489 1490 // Returns a new HandJiggle canvas 1491 mxShape.prototype.createComicCanvas = function(c) 1492 { 1493 return new HandJiggle(c, mxUtils.getValue(this.style, 'jiggle', this.defaultJiggle)); 1494 }; 1495 1496 // Overrides to avoid call to rect 1497 mxShape.prototype.createHandJiggle = function(c) 1498 { 1499 if (!this.outline && this.style != null && mxUtils.getValue(this.style, 'comic', '0') != '0') 1500 { 1501 return this.createComicCanvas(c); 1502 } 1503 1504 return null; 1505 }; 1506 1507 // Sets default jiggle for diamond 1508 mxRhombus.prototype.defaultJiggle = 2; 1509 1510 // Overrides to avoid call to rect 1511 var mxRectangleShapeIsHtmlAllowed0 = mxRectangleShape.prototype.isHtmlAllowed; 1512 mxRectangleShape.prototype.isHtmlAllowed = function() 1513 { 1514 return !this.outline && (this.style == null || (mxUtils.getValue(this.style, 'comic', '0') == '0' && 1515 mxUtils.getValue(this.style, 'sketch', (urlParams['rough'] == '1') ? '1' : '0') == '0')) && 1516 mxRectangleShapeIsHtmlAllowed0.apply(this, arguments); 1517 }; 1518 1519 var mxRectangleShapePaintBackground0 = mxRectangleShape.prototype.paintBackground; 1520 mxRectangleShape.prototype.paintBackground = function(c, x, y, w, h) 1521 { 1522 if (c.handJiggle == null || c.handJiggle.constructor != HandJiggle) 1523 { 1524 mxRectangleShapePaintBackground0.apply(this, arguments); 1525 } 1526 else 1527 { 1528 var events = true; 1529 1530 if (this.style != null) 1531 { 1532 events = mxUtils.getValue(this.style, mxConstants.STYLE_POINTER_EVENTS, '1') == '1'; 1533 } 1534 1535 if (events || (this.fill != null && this.fill != mxConstants.NONE) || 1536 (this.stroke != null && this.stroke != mxConstants.NONE)) 1537 { 1538 if (!events && (this.fill == null || this.fill == mxConstants.NONE)) 1539 { 1540 c.pointerEvents = false; 1541 } 1542 1543 c.begin(); 1544 1545 if (this.isRounded) 1546 { 1547 var r = 0; 1548 1549 if (mxUtils.getValue(this.style, mxConstants.STYLE_ABSOLUTE_ARCSIZE, 0) == '1') 1550 { 1551 r = Math.min(w / 2, Math.min(h / 2, mxUtils.getValue(this.style, 1552 mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2)); 1553 } 1554 else 1555 { 1556 var f = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, 1557 mxConstants.RECTANGLE_ROUNDING_FACTOR * 100) / 100; 1558 r = Math.min(w * f, h * f); 1559 } 1560 1561 c.moveTo(x + r, y); 1562 c.lineTo(x + w - r, y); 1563 c.quadTo(x + w, y, x + w, y + r); 1564 c.lineTo(x + w, y + h - r); 1565 c.quadTo(x + w, y + h, x + w - r, y + h); 1566 c.lineTo(x + r, y + h); 1567 c.quadTo(x, y + h, x, y + h - r); 1568 c.lineTo(x, y + r); 1569 c.quadTo(x, y, x + r, y); 1570 } 1571 else 1572 { 1573 c.moveTo(x, y); 1574 c.lineTo(x + w, y); 1575 c.lineTo(x + w, y + h); 1576 c.lineTo(x, y + h); 1577 c.lineTo(x, y); 1578 } 1579 1580 // LATER: Check if close is needed here 1581 c.close(); 1582 c.end(); 1583 1584 c.fillAndStroke(); 1585 } 1586 } 1587 }; 1588 // End of hand jiggle integration 1589 1590 // Process Shape 1591 function ProcessShape() 1592 { 1593 mxRectangleShape.call(this); 1594 }; 1595 mxUtils.extend(ProcessShape, mxRectangleShape); 1596 ProcessShape.prototype.size = 0.1; 1597 ProcessShape.prototype.fixedSize = false; 1598 1599 ProcessShape.prototype.isHtmlAllowed = function() 1600 { 1601 return false; 1602 }; 1603 ProcessShape.prototype.getLabelBounds = function(rect) 1604 { 1605 if (mxUtils.getValue(this.state.style, mxConstants.STYLE_HORIZONTAL, true) == 1606 (this.direction == null || 1607 this.direction == mxConstants.DIRECTION_EAST || 1608 this.direction == mxConstants.DIRECTION_WEST)) 1609 { 1610 var w = rect.width; 1611 var h = rect.height; 1612 var r = new mxRectangle(rect.x, rect.y, w, h); 1613 1614 var inset = w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); 1615 1616 if (this.isRounded) 1617 { 1618 var f = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, 1619 mxConstants.RECTANGLE_ROUNDING_FACTOR * 100) / 100; 1620 inset = Math.max(inset, Math.min(w * f, h * f)); 1621 } 1622 1623 r.x += Math.round(inset); 1624 r.width -= Math.round(2 * inset); 1625 1626 return r; 1627 } 1628 1629 return rect; 1630 }; 1631 1632 ProcessShape.prototype.paintForeground = function(c, x, y, w, h) 1633 { 1634 var isFixedSize = mxUtils.getValue(this.style, 'fixedSize', this.fixedSize); 1635 var inset = parseFloat(mxUtils.getValue(this.style, 'size', this.size)); 1636 1637 if (isFixedSize) 1638 { 1639 inset = Math.max(0, Math.min(w, inset)); 1640 } 1641 else 1642 { 1643 inset = w * Math.max(0, Math.min(1, inset)); 1644 } 1645 1646 if (this.isRounded) 1647 { 1648 var f = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, 1649 mxConstants.RECTANGLE_ROUNDING_FACTOR * 100) / 100; 1650 inset = Math.max(inset, Math.min(w * f, h * f)); 1651 } 1652 1653 // Crisp rendering of inner lines 1654 inset = Math.round(inset); 1655 1656 c.begin(); 1657 c.moveTo(x + inset, y); 1658 c.lineTo(x + inset, y + h); 1659 c.moveTo(x + w - inset, y); 1660 c.lineTo(x + w - inset, y + h); 1661 c.end(); 1662 c.stroke(); 1663 mxRectangleShape.prototype.paintForeground.apply(this, arguments); 1664 }; 1665 1666 mxCellRenderer.registerShape('process', ProcessShape); 1667 //Register the same shape with another name for backwards compatibility 1668 mxCellRenderer.registerShape('process2', ProcessShape); 1669 1670 // Transparent Shape 1671 function TransparentShape() 1672 { 1673 mxRectangleShape.call(this); 1674 }; 1675 mxUtils.extend(TransparentShape, mxRectangleShape); 1676 TransparentShape.prototype.paintBackground = function(c, x, y, w, h) 1677 { 1678 c.setFillColor(mxConstants.NONE); 1679 c.rect(x, y, w, h); 1680 c.fill(); 1681 }; 1682 TransparentShape.prototype.paintForeground = function(c, x, y, w, h) { }; 1683 1684 mxCellRenderer.registerShape('transparent', TransparentShape); 1685 1686 // Callout shape 1687 function CalloutShape() 1688 { 1689 mxActor.call(this); 1690 }; 1691 mxUtils.extend(CalloutShape, mxHexagon); 1692 CalloutShape.prototype.size = 30; 1693 CalloutShape.prototype.position = 0.5; 1694 CalloutShape.prototype.position2 = 0.5; 1695 CalloutShape.prototype.base = 20; 1696 CalloutShape.prototype.getLabelMargins = function() 1697 { 1698 return new mxRectangle(0, 0, 0, parseFloat(mxUtils.getValue( 1699 this.style, 'size', this.size)) * this.scale); 1700 }; 1701 CalloutShape.prototype.isRoundable = function() 1702 { 1703 return true; 1704 }; 1705 CalloutShape.prototype.redrawPath = function(c, x, y, w, h) 1706 { 1707 var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2; 1708 var s = Math.max(0, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); 1709 var dx = w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'position', this.position)))); 1710 var dx2 = w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'position2', this.position2)))); 1711 var base = Math.max(0, Math.min(w, parseFloat(mxUtils.getValue(this.style, 'base', this.base)))); 1712 1713 this.addPoints(c, [new mxPoint(0, 0), new mxPoint(w, 0), new mxPoint(w, h - s), 1714 new mxPoint(Math.min(w, dx + base), h - s), new mxPoint(dx2, h), 1715 new mxPoint(Math.max(0, dx), h - s), new mxPoint(0, h - s)], 1716 this.isRounded, arcSize, true, [4]); 1717 }; 1718 1719 mxCellRenderer.registerShape('callout', CalloutShape); 1720 1721 // Step shape 1722 function StepShape() 1723 { 1724 mxActor.call(this); 1725 }; 1726 mxUtils.extend(StepShape, mxActor); 1727 StepShape.prototype.size = 0.2; 1728 StepShape.prototype.fixedSize = 20; 1729 StepShape.prototype.isRoundable = function() 1730 { 1731 return true; 1732 }; 1733 StepShape.prototype.redrawPath = function(c, x, y, w, h) 1734 { 1735 var fixed = mxUtils.getValue(this.style, 'fixedSize', '0') != '0'; 1736 var s = (fixed) ? Math.max(0, Math.min(w, parseFloat(mxUtils.getValue(this.style, 'size', this.fixedSize)))) : 1737 w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); 1738 var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2; 1739 this.addPoints(c, [new mxPoint(0, 0), new mxPoint(w - s, 0), new mxPoint(w, h / 2), new mxPoint(w - s, h), 1740 new mxPoint(0, h), new mxPoint(s, h / 2)], this.isRounded, arcSize, true); 1741 c.end(); 1742 }; 1743 1744 mxCellRenderer.registerShape('step', StepShape); 1745 1746 // Hexagon shape 1747 function HexagonShape() 1748 { 1749 mxActor.call(this); 1750 }; 1751 mxUtils.extend(HexagonShape, mxHexagon); 1752 HexagonShape.prototype.size = 0.25; 1753 HexagonShape.prototype.fixedSize = 20; 1754 HexagonShape.prototype.isRoundable = function() 1755 { 1756 return true; 1757 }; 1758 HexagonShape.prototype.redrawPath = function(c, x, y, w, h) 1759 { 1760 var fixed = mxUtils.getValue(this.style, 'fixedSize', '0') != '0'; 1761 var s = (fixed) ? Math.max(0, Math.min(w * 0.5, parseFloat(mxUtils.getValue(this.style, 'size', this.fixedSize)))) : 1762 w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); 1763 var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2; 1764 this.addPoints(c, [new mxPoint(s, 0), new mxPoint(w - s, 0), new mxPoint(w, 0.5 * h), new mxPoint(w - s, h), 1765 new mxPoint(s, h), new mxPoint(0, 0.5 * h)], this.isRounded, arcSize, true); 1766 }; 1767 1768 mxCellRenderer.registerShape('hexagon', HexagonShape); 1769 1770 // Plus Shape 1771 function PlusShape() 1772 { 1773 mxRectangleShape.call(this); 1774 }; 1775 mxUtils.extend(PlusShape, mxRectangleShape); 1776 PlusShape.prototype.isHtmlAllowed = function() 1777 { 1778 return false; 1779 }; 1780 PlusShape.prototype.paintForeground = function(c, x, y, w, h) 1781 { 1782 var border = Math.min(w / 5, h / 5) + 1; 1783 1784 c.begin(); 1785 c.moveTo(x + w / 2, y + border); 1786 c.lineTo(x + w / 2, y + h - border); 1787 c.moveTo(x + border, y + h / 2); 1788 c.lineTo(x + w - border, y + h / 2); 1789 c.end(); 1790 c.stroke(); 1791 mxRectangleShape.prototype.paintForeground.apply(this, arguments); 1792 }; 1793 1794 mxCellRenderer.registerShape('plus', PlusShape); 1795 1796 // Overrides painting of rhombus shape to allow for double style 1797 var mxRhombusPaintVertexShape = mxRhombus.prototype.paintVertexShape; 1798 mxRhombus.prototype.getLabelBounds = function(rect) 1799 { 1800 if (this.style['double'] == 1) 1801 { 1802 var margin = (Math.max(2, this.strokewidth + 1) * 2 + parseFloat( 1803 this.style[mxConstants.STYLE_MARGIN] || 0)) * this.scale; 1804 1805 return new mxRectangle(rect.x + margin, rect.y + margin, 1806 rect.width - 2 * margin, rect.height - 2 * margin); 1807 } 1808 1809 return rect; 1810 }; 1811 mxRhombus.prototype.paintVertexShape = function(c, x, y, w, h) 1812 { 1813 mxRhombusPaintVertexShape.apply(this, arguments); 1814 1815 if (!this.outline && this.style['double'] == 1) 1816 { 1817 var margin = Math.max(2, this.strokewidth + 1) * 2 + 1818 parseFloat(this.style[mxConstants.STYLE_MARGIN] || 0); 1819 x += margin; 1820 y += margin; 1821 w -= 2 * margin; 1822 h -= 2 * margin; 1823 1824 if (w > 0 && h > 0) 1825 { 1826 c.setShadow(false); 1827 1828 // Workaround for closure compiler bug where the lines with x and y above 1829 // are removed if arguments is used as second argument in call below. 1830 mxRhombusPaintVertexShape.apply(this, [c, x, y, w, h]); 1831 } 1832 } 1833 }; 1834 1835 // CompositeShape 1836 function ExtendedShape() 1837 { 1838 mxRectangleShape.call(this); 1839 }; 1840 mxUtils.extend(ExtendedShape, mxRectangleShape); 1841 ExtendedShape.prototype.isHtmlAllowed = function() 1842 { 1843 return false; 1844 }; 1845 ExtendedShape.prototype.getLabelBounds = function(rect) 1846 { 1847 if (this.style['double'] == 1) 1848 { 1849 var margin = (Math.max(2, this.strokewidth + 1) + parseFloat( 1850 this.style[mxConstants.STYLE_MARGIN] || 0)) * this.scale; 1851 1852 return new mxRectangle(rect.x + margin, rect.y + margin, 1853 rect.width - 2 * margin, rect.height - 2 * margin); 1854 } 1855 1856 return rect; 1857 }; 1858 1859 ExtendedShape.prototype.paintForeground = function(c, x, y, w, h) 1860 { 1861 if (this.style != null) 1862 { 1863 if (!this.outline && this.style['double'] == 1) 1864 { 1865 var margin = Math.max(2, this.strokewidth + 1) + parseFloat(this.style[mxConstants.STYLE_MARGIN] || 0); 1866 x += margin; 1867 y += margin; 1868 w -= 2 * margin; 1869 h -= 2 * margin; 1870 1871 if (w > 0 && h > 0) 1872 { 1873 mxRectangleShape.prototype.paintBackground.apply(this, arguments); 1874 } 1875 } 1876 1877 c.setDashed(false); 1878 1879 // Draws the symbols defined in the style. The symbols are 1880 // numbered from 1...n. Possible postfixes are align, 1881 // verticalAlign, spacing, arcSpacing, width, height 1882 var counter = 0; 1883 var shape = null; 1884 1885 do 1886 { 1887 shape = mxCellRenderer.defaultShapes[this.style['symbol' + counter]]; 1888 1889 if (shape != null) 1890 { 1891 var align = this.style['symbol' + counter + 'Align']; 1892 var valign = this.style['symbol' + counter + 'VerticalAlign']; 1893 var width = this.style['symbol' + counter + 'Width']; 1894 var height = this.style['symbol' + counter + 'Height']; 1895 var spacing = this.style['symbol' + counter + 'Spacing'] || 0; 1896 var vspacing = this.style['symbol' + counter + 'VSpacing'] || spacing; 1897 var arcspacing = this.style['symbol' + counter + 'ArcSpacing']; 1898 1899 if (arcspacing != null) 1900 { 1901 var arcSize = this.getArcSize(w + this.strokewidth, h + this.strokewidth) * arcspacing; 1902 spacing += arcSize; 1903 vspacing += arcSize; 1904 } 1905 1906 var x2 = x; 1907 var y2 = y; 1908 1909 if (align == mxConstants.ALIGN_CENTER) 1910 { 1911 x2 += (w - width) / 2; 1912 } 1913 else if (align == mxConstants.ALIGN_RIGHT) 1914 { 1915 x2 += w - width - spacing; 1916 } 1917 else 1918 { 1919 x2 += spacing; 1920 } 1921 1922 if (valign == mxConstants.ALIGN_MIDDLE) 1923 { 1924 y2 += (h - height) / 2; 1925 } 1926 else if (valign == mxConstants.ALIGN_BOTTOM) 1927 { 1928 y2 += h - height - vspacing; 1929 } 1930 else 1931 { 1932 y2 += vspacing; 1933 } 1934 1935 c.save(); 1936 1937 // Small hack to pass style along into subshape 1938 var tmp = new shape(); 1939 // TODO: Clone style and override settings (eg. strokewidth) 1940 tmp.style = this.style; 1941 shape.prototype.paintVertexShape.call(tmp, c, x2, y2, width, height); 1942 c.restore(); 1943 } 1944 1945 counter++; 1946 } 1947 while (shape != null); 1948 } 1949 1950 // Paints glass effect 1951 mxRectangleShape.prototype.paintForeground.apply(this, arguments); 1952 }; 1953 1954 mxCellRenderer.registerShape('ext', ExtendedShape); 1955 1956 // Tape Shape, supports size style 1957 function MessageShape() 1958 { 1959 mxCylinder.call(this); 1960 }; 1961 mxUtils.extend(MessageShape, mxCylinder); 1962 MessageShape.prototype.redrawPath = function(path, x, y, w, h, isForeground) 1963 { 1964 if (isForeground) 1965 { 1966 path.moveTo(0, 0); 1967 path.lineTo(w / 2, h / 2); 1968 path.lineTo(w, 0); 1969 path.end(); 1970 } 1971 else 1972 { 1973 path.moveTo(0, 0); 1974 path.lineTo(w, 0); 1975 path.lineTo(w, h); 1976 path.lineTo(0, h); 1977 path.close(); 1978 } 1979 }; 1980 1981 mxCellRenderer.registerShape('message', MessageShape); 1982 1983 // UML Actor Shape 1984 function UmlActorShape() 1985 { 1986 mxShape.call(this); 1987 }; 1988 mxUtils.extend(UmlActorShape, mxShape); 1989 UmlActorShape.prototype.paintBackground = function(c, x, y, w, h) 1990 { 1991 c.translate(x, y); 1992 1993 // Head 1994 c.ellipse(w / 4, 0, w / 2, h / 4); 1995 c.fillAndStroke(); 1996 1997 c.begin(); 1998 c.moveTo(w / 2, h / 4); 1999 c.lineTo(w / 2, 2 * h / 3); 2000 2001 // Arms 2002 c.moveTo(w / 2, h / 3); 2003 c.lineTo(0, h / 3); 2004 c.moveTo(w / 2, h / 3); 2005 c.lineTo(w, h / 3); 2006 2007 // Legs 2008 c.moveTo(w / 2, 2 * h / 3); 2009 c.lineTo(0, h); 2010 c.moveTo(w / 2, 2 * h / 3); 2011 c.lineTo(w, h); 2012 c.end(); 2013 2014 c.stroke(); 2015 }; 2016 2017 // Replaces existing actor shape 2018 mxCellRenderer.registerShape('umlActor', UmlActorShape); 2019 2020 ////////////// UML Boundary Shape /////////////// 2021 function UmlBoundaryShape() 2022 { 2023 mxShape.call(this); 2024 }; 2025 mxUtils.extend(UmlBoundaryShape, mxShape); 2026 UmlBoundaryShape.prototype.getLabelMargins = function(rect) 2027 { 2028 return new mxRectangle(rect.width / 6, 0, 0, 0); 2029 }; 2030 UmlBoundaryShape.prototype.paintBackground = function(c, x, y, w, h) 2031 { 2032 c.translate(x, y); 2033 2034 // Base line 2035 c.begin(); 2036 c.moveTo(0, h / 4); 2037 c.lineTo(0, h * 3 / 4); 2038 c.end(); 2039 c.stroke(); 2040 2041 // Horizontal line 2042 c.begin(); 2043 c.moveTo(0, h / 2); 2044 c.lineTo(w / 6, h / 2); 2045 c.end(); 2046 c.stroke(); 2047 2048 // Circle 2049 c.ellipse(w / 6, 0, w * 5 / 6, h); 2050 c.fillAndStroke(); 2051 }; 2052 2053 mxCellRenderer.registerShape('umlBoundary', UmlBoundaryShape); 2054 2055 // UML Entity Shape 2056 function UmlEntityShape() 2057 { 2058 mxEllipse.call(this); 2059 }; 2060 mxUtils.extend(UmlEntityShape, mxEllipse); 2061 UmlEntityShape.prototype.paintVertexShape = function(c, x, y, w, h) 2062 { 2063 mxEllipse.prototype.paintVertexShape.apply(this, arguments); 2064 2065 c.begin(); 2066 c.moveTo(x + w / 8, y + h); 2067 c.lineTo(x + w * 7 / 8, y + h); 2068 c.end(); 2069 c.stroke(); 2070 }; 2071 2072 mxCellRenderer.registerShape('umlEntity', UmlEntityShape); 2073 2074 // UML Destroy Shape 2075 function UmlDestroyShape() 2076 { 2077 mxShape.call(this); 2078 }; 2079 mxUtils.extend(UmlDestroyShape, mxShape); 2080 UmlDestroyShape.prototype.paintVertexShape = function(c, x, y, w, h) 2081 { 2082 c.translate(x, y); 2083 2084 c.begin(); 2085 c.moveTo(w, 0); 2086 c.lineTo(0, h); 2087 c.moveTo(0, 0); 2088 c.lineTo(w, h); 2089 c.end(); 2090 c.stroke(); 2091 }; 2092 2093 mxCellRenderer.registerShape('umlDestroy', UmlDestroyShape); 2094 2095 // UML Control Shape 2096 function UmlControlShape() 2097 { 2098 mxShape.call(this); 2099 }; 2100 mxUtils.extend(UmlControlShape, mxShape); 2101 UmlControlShape.prototype.getLabelBounds = function(rect) 2102 { 2103 return new mxRectangle(rect.x, rect.y + rect.height / 8, rect.width, rect.height * 7 / 8); 2104 }; 2105 UmlControlShape.prototype.paintBackground = function(c, x, y, w, h) 2106 { 2107 c.translate(x, y); 2108 2109 // Upper line 2110 c.begin(); 2111 c.moveTo(w * 3 / 8, h / 8 * 1.1); 2112 c.lineTo(w * 5 / 8, 0); 2113 c.end(); 2114 c.stroke(); 2115 2116 // Circle 2117 c.ellipse(0, h / 8, w, h * 7 / 8); 2118 c.fillAndStroke(); 2119 }; 2120 UmlControlShape.prototype.paintForeground = function(c, x, y, w, h) 2121 { 2122 // Lower line 2123 c.begin(); 2124 c.moveTo(w * 3 / 8, h / 8 * 1.1); 2125 c.lineTo(w * 5 / 8, h / 4); 2126 c.end(); 2127 c.stroke(); 2128 }; 2129 2130 // Replaces existing actor shape 2131 mxCellRenderer.registerShape('umlControl', UmlControlShape); 2132 2133 // UML Lifeline Shape 2134 function UmlLifeline() 2135 { 2136 mxRectangleShape.call(this); 2137 }; 2138 mxUtils.extend(UmlLifeline, mxRectangleShape); 2139 UmlLifeline.prototype.size = 40; 2140 UmlLifeline.prototype.isHtmlAllowed = function() 2141 { 2142 return false; 2143 }; 2144 UmlLifeline.prototype.getLabelBounds = function(rect) 2145 { 2146 var size = Math.max(0, Math.min(rect.height, parseFloat( 2147 mxUtils.getValue(this.style, 'size', this.size)) * this.scale)); 2148 2149 return new mxRectangle(rect.x, rect.y, rect.width, size); 2150 }; 2151 UmlLifeline.prototype.paintBackground = function(c, x, y, w, h) 2152 { 2153 var size = Math.max(0, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); 2154 var participant = mxUtils.getValue(this.style, 'participant'); 2155 2156 if (participant == null || this.state == null) 2157 { 2158 mxRectangleShape.prototype.paintBackground.call(this, c, x, y, w, size); 2159 } 2160 else 2161 { 2162 var ctor = this.state.view.graph.cellRenderer.getShape(participant); 2163 2164 if (ctor != null && ctor != UmlLifeline) 2165 { 2166 var shape = new ctor(); 2167 shape.apply(this.state); 2168 c.save(); 2169 shape.paintVertexShape(c, x, y, w, size); 2170 c.restore(); 2171 } 2172 } 2173 2174 if (size < h) 2175 { 2176 c.setDashed(mxUtils.getValue(this.style, 'lifelineDashed', '1') == '1'); 2177 c.begin(); 2178 c.moveTo(x + w / 2, y + size); 2179 c.lineTo(x + w / 2, y + h); 2180 c.end(); 2181 c.stroke(); 2182 } 2183 }; 2184 UmlLifeline.prototype.paintForeground = function(c, x, y, w, h) 2185 { 2186 var size = Math.max(0, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); 2187 mxRectangleShape.prototype.paintForeground.call(this, c, x, y, w, Math.min(h, size)); 2188 }; 2189 2190 mxCellRenderer.registerShape('umlLifeline', UmlLifeline); 2191 2192 // UML Frame Shape 2193 function UmlFrame() 2194 { 2195 mxShape.call(this); 2196 }; 2197 mxUtils.extend(UmlFrame, mxShape); 2198 UmlFrame.prototype.width = 60; 2199 UmlFrame.prototype.height = 30; 2200 UmlFrame.prototype.corner = 10; 2201 UmlFrame.prototype.getLabelMargins = function(rect) 2202 { 2203 return new mxRectangle(0, 0, 2204 rect.width - (parseFloat(mxUtils.getValue(this.style, 'width', this.width) * this.scale)), 2205 rect.height - (parseFloat(mxUtils.getValue(this.style, 'height', this.height) * this.scale))); 2206 }; 2207 UmlFrame.prototype.paintBackground = function(c, x, y, w, h) 2208 { 2209 var co = this.corner; 2210 var w0 = Math.min(w, Math.max(co, parseFloat(mxUtils.getValue(this.style, 'width', this.width)))); 2211 var h0 = Math.min(h, Math.max(co * 1.5, parseFloat(mxUtils.getValue(this.style, 'height', this.height)))); 2212 var bg = mxUtils.getValue(this.style, mxConstants.STYLE_SWIMLANE_FILLCOLOR, mxConstants.NONE); 2213 2214 if (bg != mxConstants.NONE) 2215 { 2216 c.setFillColor(bg); 2217 c.rect(x, y, w, h); 2218 c.fill(); 2219 } 2220 2221 if (this.fill != null && this.fill != mxConstants.NONE && this.gradient && this.gradient != mxConstants.NONE) 2222 { 2223 var b = this.getGradientBounds(c, x, y, w, h); 2224 c.setGradient(this.fill, this.gradient, x, y, w, h, this.gradientDirection); 2225 } 2226 else 2227 { 2228 c.setFillColor(this.fill); 2229 } 2230 2231 c.begin(); 2232 c.moveTo(x, y); 2233 c.lineTo(x + w0, y); 2234 c.lineTo(x + w0, y + Math.max(0, h0 - co * 1.5)); 2235 c.lineTo(x + Math.max(0, w0 - co), y + h0); 2236 c.lineTo(x, y + h0); 2237 c.close(); 2238 c.fillAndStroke(); 2239 2240 c.begin(); 2241 c.moveTo(x + w0, y); 2242 c.lineTo(x + w, y); 2243 c.lineTo(x + w, y + h); 2244 c.lineTo(x, y + h); 2245 c.lineTo(x, y + h0); 2246 c.stroke(); 2247 }; 2248 2249 mxCellRenderer.registerShape('umlFrame', UmlFrame); 2250 2251 mxPerimeter.CenterPerimeter = function (bounds, vertex, next, orthogonal) 2252 { 2253 return new mxPoint(bounds.getCenterX(), bounds.getCenterY()); 2254 }; 2255 2256 mxStyleRegistry.putValue('centerPerimeter', mxPerimeter.CenterPerimeter); 2257 2258 mxPerimeter.LifelinePerimeter = function (bounds, vertex, next, orthogonal) 2259 { 2260 var size = UmlLifeline.prototype.size; 2261 2262 if (vertex != null) 2263 { 2264 size = mxUtils.getValue(vertex.style, 'size', size) * vertex.view.scale; 2265 } 2266 2267 var sw = (parseFloat(vertex.style[mxConstants.STYLE_STROKEWIDTH] || 1) * vertex.view.scale / 2) - 1; 2268 2269 if (next.x < bounds.getCenterX()) 2270 { 2271 sw += 1; 2272 sw *= -1; 2273 } 2274 2275 return new mxPoint(bounds.getCenterX() + sw, Math.min(bounds.y + bounds.height, 2276 Math.max(bounds.y + size, next.y))); 2277 }; 2278 2279 mxStyleRegistry.putValue('lifelinePerimeter', mxPerimeter.LifelinePerimeter); 2280 2281 mxPerimeter.OrthogonalPerimeter = function (bounds, vertex, next, orthogonal) 2282 { 2283 orthogonal = true; 2284 2285 return mxPerimeter.RectanglePerimeter.apply(this, arguments); 2286 }; 2287 2288 mxStyleRegistry.putValue('orthogonalPerimeter', mxPerimeter.OrthogonalPerimeter); 2289 2290 mxPerimeter.BackbonePerimeter = function (bounds, vertex, next, orthogonal) 2291 { 2292 var sw = (parseFloat(vertex.style[mxConstants.STYLE_STROKEWIDTH] || 1) * vertex.view.scale / 2) - 1; 2293 2294 if (vertex.style['backboneSize'] != null) 2295 { 2296 sw += (parseFloat(vertex.style['backboneSize']) * vertex.view.scale / 2) - 1; 2297 } 2298 2299 if (vertex.style[mxConstants.STYLE_DIRECTION] == 'south' || 2300 vertex.style[mxConstants.STYLE_DIRECTION] == 'north') 2301 { 2302 if (next.x < bounds.getCenterX()) 2303 { 2304 sw += 1; 2305 sw *= -1; 2306 } 2307 2308 return new mxPoint(bounds.getCenterX() + sw, Math.min(bounds.y + bounds.height, 2309 Math.max(bounds.y, next.y))); 2310 } 2311 else 2312 { 2313 if (next.y < bounds.getCenterY()) 2314 { 2315 sw += 1; 2316 sw *= -1; 2317 } 2318 2319 return new mxPoint(Math.min(bounds.x + bounds.width, Math.max(bounds.x, next.x)), 2320 bounds.getCenterY() + sw); 2321 } 2322 }; 2323 2324 mxStyleRegistry.putValue('backbonePerimeter', mxPerimeter.BackbonePerimeter); 2325 2326 // Callout Perimeter 2327 mxPerimeter.CalloutPerimeter = function (bounds, vertex, next, orthogonal) 2328 { 2329 return mxPerimeter.RectanglePerimeter(mxUtils.getDirectedBounds(bounds, new mxRectangle(0, 0, 0, 2330 Math.max(0, Math.min(bounds.height, parseFloat(mxUtils.getValue(vertex.style, 'size', 2331 CalloutShape.prototype.size)) * vertex.view.scale))), 2332 vertex.style), vertex, next, orthogonal); 2333 }; 2334 2335 mxStyleRegistry.putValue('calloutPerimeter', mxPerimeter.CalloutPerimeter); 2336 2337 // Parallelogram Perimeter 2338 mxPerimeter.ParallelogramPerimeter = function (bounds, vertex, next, orthogonal) 2339 { 2340 var fixed = mxUtils.getValue(vertex.style, 'fixedSize', '0') != '0'; 2341 var size = (fixed) ? ParallelogramShape.prototype.fixedSize : ParallelogramShape.prototype.size; 2342 2343 if (vertex != null) 2344 { 2345 size = mxUtils.getValue(vertex.style, 'size', size); 2346 } 2347 2348 if (fixed) 2349 { 2350 size *= vertex.view.scale; 2351 } 2352 2353 var x = bounds.x; 2354 var y = bounds.y; 2355 var w = bounds.width; 2356 var h = bounds.height; 2357 2358 var direction = (vertex != null) ? mxUtils.getValue( 2359 vertex.style, mxConstants.STYLE_DIRECTION, 2360 mxConstants.DIRECTION_EAST) : mxConstants.DIRECTION_EAST; 2361 var vertical = direction == mxConstants.DIRECTION_NORTH || 2362 direction == mxConstants.DIRECTION_SOUTH; 2363 var points; 2364 2365 if (vertical) 2366 { 2367 var dy = (fixed) ? Math.max(0, Math.min(h, size)) : h * Math.max(0, Math.min(1, size)); 2368 points = [new mxPoint(x, y), new mxPoint(x + w, y + dy), 2369 new mxPoint(x + w, y + h), new mxPoint(x, y + h - dy), new mxPoint(x, y)]; 2370 } 2371 else 2372 { 2373 var dx = (fixed) ? Math.max(0, Math.min(w * 0.5, size)) : w * Math.max(0, Math.min(1, size)); 2374 points = [new mxPoint(x + dx, y), new mxPoint(x + w, y), 2375 new mxPoint(x + w - dx, y + h), new mxPoint(x, y + h), new mxPoint(x + dx, y)]; 2376 } 2377 2378 var cx = bounds.getCenterX(); 2379 var cy = bounds.getCenterY(); 2380 2381 var p1 = new mxPoint(cx, cy); 2382 2383 if (orthogonal) 2384 { 2385 if (next.x < x || next.x > x + w) 2386 { 2387 p1.y = next.y; 2388 } 2389 else 2390 { 2391 p1.x = next.x; 2392 } 2393 } 2394 2395 return mxUtils.getPerimeterPoint(points, p1, next); 2396 }; 2397 2398 mxStyleRegistry.putValue('parallelogramPerimeter', mxPerimeter.ParallelogramPerimeter); 2399 2400 // Trapezoid Perimeter 2401 mxPerimeter.TrapezoidPerimeter = function (bounds, vertex, next, orthogonal) 2402 { 2403 var fixed = mxUtils.getValue(vertex.style, 'fixedSize', '0') != '0'; 2404 var size = (fixed) ? TrapezoidShape.prototype.fixedSize : TrapezoidShape.prototype.size; 2405 2406 if (vertex != null) 2407 { 2408 size = mxUtils.getValue(vertex.style, 'size', size); 2409 } 2410 2411 if (fixed) 2412 { 2413 size *= vertex.view.scale; 2414 } 2415 2416 var x = bounds.x; 2417 var y = bounds.y; 2418 var w = bounds.width; 2419 var h = bounds.height; 2420 2421 var direction = (vertex != null) ? mxUtils.getValue( 2422 vertex.style, mxConstants.STYLE_DIRECTION, 2423 mxConstants.DIRECTION_EAST) : mxConstants.DIRECTION_EAST; 2424 var points = []; 2425 2426 if (direction == mxConstants.DIRECTION_EAST) 2427 { 2428 var dx = (fixed) ? Math.max(0, Math.min(w * 0.5, size)) : w * Math.max(0, Math.min(1, size)); 2429 points = [new mxPoint(x + dx, y), new mxPoint(x + w - dx, y), 2430 new mxPoint(x + w, y + h), new mxPoint(x, y + h), new mxPoint(x + dx, y)]; 2431 } 2432 else if (direction == mxConstants.DIRECTION_WEST) 2433 { 2434 var dx = (fixed) ? Math.max(0, Math.min(w, size)) : w * Math.max(0, Math.min(1, size)); 2435 points = [new mxPoint(x, y), new mxPoint(x + w, y), 2436 new mxPoint(x + w - dx, y + h), new mxPoint(x + dx, y + h), new mxPoint(x, y)]; 2437 } 2438 else if (direction == mxConstants.DIRECTION_NORTH) 2439 { 2440 var dy = (fixed) ? Math.max(0, Math.min(h, size)) : h * Math.max(0, Math.min(1, size)); 2441 points = [new mxPoint(x, y + dy), new mxPoint(x + w, y), 2442 new mxPoint(x + w, y + h), new mxPoint(x, y + h - dy), new mxPoint(x, y + dy)]; 2443 } 2444 else 2445 { 2446 var dy = (fixed) ? Math.max(0, Math.min(h, size)) : h * Math.max(0, Math.min(1, size)); 2447 points = [new mxPoint(x, y), new mxPoint(x + w, y + dy), 2448 new mxPoint(x + w, y + h - dy), new mxPoint(x, y + h), new mxPoint(x, y)]; 2449 } 2450 2451 var cx = bounds.getCenterX(); 2452 var cy = bounds.getCenterY(); 2453 2454 var p1 = new mxPoint(cx, cy); 2455 2456 if (orthogonal) 2457 { 2458 if (next.x < x || next.x > x + w) 2459 { 2460 p1.y = next.y; 2461 } 2462 else 2463 { 2464 p1.x = next.x; 2465 } 2466 } 2467 2468 return mxUtils.getPerimeterPoint(points, p1, next); 2469 }; 2470 2471 mxStyleRegistry.putValue('trapezoidPerimeter', mxPerimeter.TrapezoidPerimeter); 2472 2473 // Step Perimeter 2474 mxPerimeter.StepPerimeter = function (bounds, vertex, next, orthogonal) 2475 { 2476 var fixed = mxUtils.getValue(vertex.style, 'fixedSize', '0') != '0'; 2477 var size = (fixed) ? StepShape.prototype.fixedSize : StepShape.prototype.size; 2478 2479 if (vertex != null) 2480 { 2481 size = mxUtils.getValue(vertex.style, 'size', size); 2482 } 2483 2484 if (fixed) 2485 { 2486 size *= vertex.view.scale; 2487 } 2488 2489 var x = bounds.x; 2490 var y = bounds.y; 2491 var w = bounds.width; 2492 var h = bounds.height; 2493 2494 var cx = bounds.getCenterX(); 2495 var cy = bounds.getCenterY(); 2496 2497 var direction = (vertex != null) ? mxUtils.getValue( 2498 vertex.style, mxConstants.STYLE_DIRECTION, 2499 mxConstants.DIRECTION_EAST) : mxConstants.DIRECTION_EAST; 2500 var points; 2501 2502 if (direction == mxConstants.DIRECTION_EAST) 2503 { 2504 var dx = (fixed) ? Math.max(0, Math.min(w, size)) : w * Math.max(0, Math.min(1, size)); 2505 points = [new mxPoint(x, y), new mxPoint(x + w - dx, y), new mxPoint(x + w, cy), 2506 new mxPoint(x + w - dx, y + h), new mxPoint(x, y + h), 2507 new mxPoint(x + dx, cy), new mxPoint(x, y)]; 2508 } 2509 else if (direction == mxConstants.DIRECTION_WEST) 2510 { 2511 var dx = (fixed) ? Math.max(0, Math.min(w, size)) : w * Math.max(0, Math.min(1, size)); 2512 points = [new mxPoint(x + dx, y), new mxPoint(x + w, y), new mxPoint(x + w - dx, cy), 2513 new mxPoint(x + w, y + h), new mxPoint(x + dx, y + h), 2514 new mxPoint(x, cy), new mxPoint(x + dx, y)]; 2515 } 2516 else if (direction == mxConstants.DIRECTION_NORTH) 2517 { 2518 var dy = (fixed) ? Math.max(0, Math.min(h, size)) : h * Math.max(0, Math.min(1, size)); 2519 points = [new mxPoint(x, y + dy), new mxPoint(cx, y), new mxPoint(x + w, y + dy), 2520 new mxPoint(x + w, y + h), new mxPoint(cx, y + h - dy), 2521 new mxPoint(x, y + h), new mxPoint(x, y + dy)]; 2522 } 2523 else 2524 { 2525 var dy = (fixed) ? Math.max(0, Math.min(h, size)) : h * Math.max(0, Math.min(1, size)); 2526 points = [new mxPoint(x, y), new mxPoint(cx, y + dy), new mxPoint(x + w, y), 2527 new mxPoint(x + w, y + h - dy), new mxPoint(cx, y + h), 2528 new mxPoint(x, y + h - dy), new mxPoint(x, y)]; 2529 } 2530 2531 var p1 = new mxPoint(cx, cy); 2532 2533 if (orthogonal) 2534 { 2535 if (next.x < x || next.x > x + w) 2536 { 2537 p1.y = next.y; 2538 } 2539 else 2540 { 2541 p1.x = next.x; 2542 } 2543 } 2544 2545 return mxUtils.getPerimeterPoint(points, p1, next); 2546 }; 2547 2548 mxStyleRegistry.putValue('stepPerimeter', mxPerimeter.StepPerimeter); 2549 2550 // Hexagon Perimeter 2 (keep existing one) 2551 mxPerimeter.HexagonPerimeter2 = function (bounds, vertex, next, orthogonal) 2552 { 2553 var fixed = mxUtils.getValue(vertex.style, 'fixedSize', '0') != '0'; 2554 var size = (fixed) ? HexagonShape.prototype.fixedSize : HexagonShape.prototype.size; 2555 2556 if (vertex != null) 2557 { 2558 size = mxUtils.getValue(vertex.style, 'size', size); 2559 } 2560 2561 if (fixed) 2562 { 2563 size *= vertex.view.scale; 2564 } 2565 2566 var x = bounds.x; 2567 var y = bounds.y; 2568 var w = bounds.width; 2569 var h = bounds.height; 2570 2571 var cx = bounds.getCenterX(); 2572 var cy = bounds.getCenterY(); 2573 2574 var direction = (vertex != null) ? mxUtils.getValue( 2575 vertex.style, mxConstants.STYLE_DIRECTION, 2576 mxConstants.DIRECTION_EAST) : mxConstants.DIRECTION_EAST; 2577 var vertical = direction == mxConstants.DIRECTION_NORTH || 2578 direction == mxConstants.DIRECTION_SOUTH; 2579 var points; 2580 2581 if (vertical) 2582 { 2583 var dy = (fixed) ? Math.max(0, Math.min(h, size)) : h * Math.max(0, Math.min(1, size)); 2584 points = [new mxPoint(cx, y), new mxPoint(x + w, y + dy), new mxPoint(x + w, y + h - dy), 2585 new mxPoint(cx, y + h), new mxPoint(x, y + h - dy), 2586 new mxPoint(x, y + dy), new mxPoint(cx, y)]; 2587 } 2588 else 2589 { 2590 var dx = (fixed) ? Math.max(0, Math.min(w, size)) : w * Math.max(0, Math.min(1, size)); 2591 points = [new mxPoint(x + dx, y), new mxPoint(x + w - dx, y), new mxPoint(x + w, cy), 2592 new mxPoint(x + w - dx, y + h), new mxPoint(x + dx, y + h), 2593 new mxPoint(x, cy), new mxPoint(x + dx, y)]; 2594 } 2595 2596 var p1 = new mxPoint(cx, cy); 2597 2598 if (orthogonal) 2599 { 2600 if (next.x < x || next.x > x + w) 2601 { 2602 p1.y = next.y; 2603 } 2604 else 2605 { 2606 p1.x = next.x; 2607 } 2608 } 2609 2610 return mxUtils.getPerimeterPoint(points, p1, next); 2611 }; 2612 2613 mxStyleRegistry.putValue('hexagonPerimeter2', mxPerimeter.HexagonPerimeter2); 2614 2615 // Provided Interface Shape (aka Lollipop) 2616 function LollipopShape() 2617 { 2618 mxShape.call(this); 2619 }; 2620 mxUtils.extend(LollipopShape, mxShape); 2621 LollipopShape.prototype.size = 10; 2622 LollipopShape.prototype.paintBackground = function(c, x, y, w, h) 2623 { 2624 var sz = parseFloat(mxUtils.getValue(this.style, 'size', this.size)); 2625 c.translate(x, y); 2626 2627 c.ellipse((w - sz) / 2, 0, sz, sz); 2628 c.fillAndStroke(); 2629 2630 c.begin(); 2631 c.moveTo(w / 2, sz); 2632 c.lineTo(w / 2, h); 2633 c.end(); 2634 c.stroke(); 2635 }; 2636 2637 mxCellRenderer.registerShape('lollipop', LollipopShape); 2638 2639 // Required Interface Shape 2640 function RequiresShape() 2641 { 2642 mxShape.call(this); 2643 }; 2644 mxUtils.extend(RequiresShape, mxShape); 2645 RequiresShape.prototype.size = 10; 2646 RequiresShape.prototype.inset = 2; 2647 RequiresShape.prototype.paintBackground = function(c, x, y, w, h) 2648 { 2649 var sz = parseFloat(mxUtils.getValue(this.style, 'size', this.size)); 2650 var inset = parseFloat(mxUtils.getValue(this.style, 'inset', this.inset)) + this.strokewidth; 2651 c.translate(x, y); 2652 2653 c.begin(); 2654 c.moveTo(w / 2, sz + inset); 2655 c.lineTo(w / 2, h); 2656 c.end(); 2657 c.stroke(); 2658 2659 c.begin(); 2660 c.moveTo((w - sz) / 2 - inset, sz / 2); 2661 c.quadTo((w - sz) / 2 - inset, sz + inset, w / 2, sz + inset); 2662 c.quadTo((w + sz) / 2 + inset, sz + inset, (w + sz) / 2 + inset, sz / 2); 2663 c.end(); 2664 c.stroke(); 2665 }; 2666 2667 mxCellRenderer.registerShape('requires', RequiresShape); 2668 2669 // Required Interface Shape 2670 function RequiredInterfaceShape() 2671 { 2672 mxShape.call(this); 2673 }; 2674 mxUtils.extend(RequiredInterfaceShape, mxShape); 2675 2676 RequiredInterfaceShape.prototype.paintBackground = function(c, x, y, w, h) 2677 { 2678 c.translate(x, y); 2679 2680 c.begin(); 2681 c.moveTo(0, 0); 2682 c.quadTo(w, 0, w, h / 2); 2683 c.quadTo(w, h, 0, h); 2684 c.end(); 2685 c.stroke(); 2686 }; 2687 2688 mxCellRenderer.registerShape('requiredInterface', RequiredInterfaceShape); 2689 2690 // Provided and Required Interface Shape 2691 function ProvidedRequiredInterfaceShape() 2692 { 2693 mxShape.call(this); 2694 }; 2695 mxUtils.extend(ProvidedRequiredInterfaceShape, mxShape); 2696 ProvidedRequiredInterfaceShape.prototype.inset = 2; 2697 ProvidedRequiredInterfaceShape.prototype.paintBackground = function(c, x, y, w, h) 2698 { 2699 var inset = parseFloat(mxUtils.getValue(this.style, 'inset', this.inset)) + this.strokewidth; 2700 c.translate(x, y); 2701 2702 c.ellipse(0, inset, w - 2 * inset, h - 2 * inset); 2703 c.fillAndStroke(); 2704 2705 c.begin(); 2706 c.moveTo(w / 2, 0); 2707 c.quadTo(w, 0, w, h / 2); 2708 c.quadTo(w, h, w / 2, h); 2709 c.end(); 2710 c.stroke(); 2711 }; 2712 2713 mxCellRenderer.registerShape('providedRequiredInterface', ProvidedRequiredInterfaceShape); 2714 2715 // Module shape 2716 function ModuleShape() 2717 { 2718 mxCylinder.call(this); 2719 }; 2720 mxUtils.extend(ModuleShape, mxCylinder); 2721 ModuleShape.prototype.jettyWidth = 20; 2722 ModuleShape.prototype.jettyHeight = 10; 2723 ModuleShape.prototype.redrawPath = function(path, x, y, w, h, isForeground) 2724 { 2725 var dx = parseFloat(mxUtils.getValue(this.style, 'jettyWidth', this.jettyWidth)); 2726 var dy = parseFloat(mxUtils.getValue(this.style, 'jettyHeight', this.jettyHeight)); 2727 var x0 = dx / 2; 2728 var x1 = x0 + dx / 2; 2729 var y0 = Math.min(dy, h - dy); 2730 var y1 = Math.min(y0 + 2 * dy, h - dy); 2731 2732 if (isForeground) 2733 { 2734 path.moveTo(x0, y0); 2735 path.lineTo(x1, y0); 2736 path.lineTo(x1, y0 + dy); 2737 path.lineTo(x0, y0 + dy); 2738 path.moveTo(x0, y1); 2739 path.lineTo(x1, y1); 2740 path.lineTo(x1, y1 + dy); 2741 path.lineTo(x0, y1 + dy); 2742 path.end(); 2743 } 2744 else 2745 { 2746 path.moveTo(x0, 0); 2747 path.lineTo(w, 0); 2748 path.lineTo(w, h); 2749 path.lineTo(x0, h); 2750 path.lineTo(x0, y1 + dy); 2751 path.lineTo(0, y1 + dy); 2752 path.lineTo(0, y1); 2753 path.lineTo(x0, y1); 2754 path.lineTo(x0, y0 + dy); 2755 path.lineTo(0, y0 + dy); 2756 path.lineTo(0, y0); 2757 path.lineTo(x0, y0); 2758 path.close(); 2759 path.end(); 2760 } 2761 }; 2762 2763 mxCellRenderer.registerShape('module', ModuleShape); 2764 2765 // Component shape 2766 function ComponentShape() 2767 { 2768 mxCylinder.call(this); 2769 }; 2770 mxUtils.extend(ComponentShape, mxCylinder); 2771 ComponentShape.prototype.jettyWidth = 32; 2772 ComponentShape.prototype.jettyHeight = 12; 2773 ComponentShape.prototype.redrawPath = function(path, x, y, w, h, isForeground) 2774 { 2775 var dx = parseFloat(mxUtils.getValue(this.style, 'jettyWidth', this.jettyWidth)); 2776 var dy = parseFloat(mxUtils.getValue(this.style, 'jettyHeight', this.jettyHeight)); 2777 var x0 = dx / 2; 2778 var x1 = x0 + dx / 2; 2779 var y0 = 0.3 * h - dy / 2; 2780 var y1 = 0.7 * h - dy / 2; 2781 2782 if (isForeground) 2783 { 2784 path.moveTo(x0, y0); 2785 path.lineTo(x1, y0); 2786 path.lineTo(x1, y0 + dy); 2787 path.lineTo(x0, y0 + dy); 2788 path.moveTo(x0, y1); 2789 path.lineTo(x1, y1); 2790 path.lineTo(x1, y1 + dy); 2791 path.lineTo(x0, y1 + dy); 2792 path.end(); 2793 } 2794 else 2795 { 2796 path.moveTo(x0, 0); 2797 path.lineTo(w, 0); 2798 path.lineTo(w, h); 2799 path.lineTo(x0, h); 2800 path.lineTo(x0, y1 + dy); 2801 path.lineTo(0, y1 + dy); 2802 path.lineTo(0, y1); 2803 path.lineTo(x0, y1); 2804 path.lineTo(x0, y0 + dy); 2805 path.lineTo(0, y0 + dy); 2806 path.lineTo(0, y0); 2807 path.lineTo(x0, y0); 2808 path.close(); 2809 path.end(); 2810 } 2811 }; 2812 2813 mxCellRenderer.registerShape('component', ComponentShape); 2814 2815 // Associative entity derived from rectangle shape 2816 function AssociativeEntity() 2817 { 2818 mxRectangleShape.call(this); 2819 }; 2820 mxUtils.extend(AssociativeEntity, mxRectangleShape); 2821 AssociativeEntity.prototype.paintForeground = function(c, x, y, w, h) 2822 { 2823 var hw = w / 2; 2824 var hh = h / 2; 2825 2826 var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2; 2827 c.begin(); 2828 this.addPoints(c, [new mxPoint(x + hw, y), new mxPoint(x + w, y + hh), new mxPoint(x + hw, y + h), 2829 new mxPoint(x, y + hh)], this.isRounded, arcSize, true); 2830 c.stroke(); 2831 2832 mxRectangleShape.prototype.paintForeground.apply(this, arguments); 2833 }; 2834 2835 mxCellRenderer.registerShape('associativeEntity', AssociativeEntity); 2836 2837 // State Shapes derives from double ellipse 2838 function StateShape() 2839 { 2840 mxDoubleEllipse.call(this); 2841 }; 2842 mxUtils.extend(StateShape, mxDoubleEllipse); 2843 StateShape.prototype.outerStroke = true; 2844 StateShape.prototype.paintVertexShape = function(c, x, y, w, h) 2845 { 2846 var inset = Math.min(4, Math.min(w / 5, h / 5)); 2847 2848 if (w > 0 && h > 0) 2849 { 2850 c.ellipse(x + inset, y + inset, w - 2 * inset, h - 2 * inset); 2851 c.fillAndStroke(); 2852 } 2853 2854 c.setShadow(false); 2855 2856 if (this.outerStroke) 2857 { 2858 c.ellipse(x, y, w, h); 2859 c.stroke(); 2860 } 2861 }; 2862 2863 mxCellRenderer.registerShape('endState', StateShape); 2864 2865 function StartStateShape() 2866 { 2867 StateShape.call(this); 2868 }; 2869 mxUtils.extend(StartStateShape, StateShape); 2870 StartStateShape.prototype.outerStroke = false; 2871 2872 mxCellRenderer.registerShape('startState', StartStateShape); 2873 2874 // Link shape 2875 function LinkShape() 2876 { 2877 mxArrowConnector.call(this); 2878 this.spacing = 0; 2879 }; 2880 mxUtils.extend(LinkShape, mxArrowConnector); 2881 LinkShape.prototype.defaultWidth = 4; 2882 2883 LinkShape.prototype.isOpenEnded = function() 2884 { 2885 return true; 2886 }; 2887 2888 LinkShape.prototype.getEdgeWidth = function() 2889 { 2890 return mxUtils.getNumber(this.style, 'width', this.defaultWidth) + Math.max(0, this.strokewidth - 1); 2891 }; 2892 2893 LinkShape.prototype.isArrowRounded = function() 2894 { 2895 return this.isRounded; 2896 }; 2897 2898 // Registers the link shape 2899 mxCellRenderer.registerShape('link', LinkShape); 2900 2901 // Generic arrow 2902 function FlexArrowShape() 2903 { 2904 mxArrowConnector.call(this); 2905 this.spacing = 0; 2906 }; 2907 mxUtils.extend(FlexArrowShape, mxArrowConnector); 2908 FlexArrowShape.prototype.defaultWidth = 10; 2909 FlexArrowShape.prototype.defaultArrowWidth = 20; 2910 2911 FlexArrowShape.prototype.getStartArrowWidth = function() 2912 { 2913 return this.getEdgeWidth() + mxUtils.getNumber(this.style, 'startWidth', this.defaultArrowWidth); 2914 }; 2915 2916 FlexArrowShape.prototype.getEndArrowWidth = function() 2917 { 2918 return this.getEdgeWidth() + mxUtils.getNumber(this.style, 'endWidth', this.defaultArrowWidth);; 2919 }; 2920 2921 FlexArrowShape.prototype.getEdgeWidth = function() 2922 { 2923 return mxUtils.getNumber(this.style, 'width', this.defaultWidth) + Math.max(0, this.strokewidth - 1); 2924 }; 2925 2926 // Registers the link shape 2927 mxCellRenderer.registerShape('flexArrow', FlexArrowShape); 2928 2929 // Manual Input shape 2930 function ManualInputShape() 2931 { 2932 mxActor.call(this); 2933 }; 2934 mxUtils.extend(ManualInputShape, mxActor); 2935 ManualInputShape.prototype.size = 30; 2936 ManualInputShape.prototype.isRoundable = function() 2937 { 2938 return true; 2939 }; 2940 ManualInputShape.prototype.redrawPath = function(c, x, y, w, h) 2941 { 2942 var s = Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size))); 2943 var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2; 2944 this.addPoints(c, [new mxPoint(0, h), new mxPoint(0, s), new mxPoint(w, 0), new mxPoint(w, h)], 2945 this.isRounded, arcSize, true); 2946 c.end(); 2947 }; 2948 2949 mxCellRenderer.registerShape('manualInput', ManualInputShape); 2950 2951 // Internal storage 2952 function InternalStorageShape() 2953 { 2954 mxRectangleShape.call(this); 2955 }; 2956 mxUtils.extend(InternalStorageShape, mxRectangleShape); 2957 InternalStorageShape.prototype.dx = 20; 2958 InternalStorageShape.prototype.dy = 20; 2959 InternalStorageShape.prototype.isHtmlAllowed = function() 2960 { 2961 return false; 2962 }; 2963 InternalStorageShape.prototype.paintForeground = function(c, x, y, w, h) 2964 { 2965 mxRectangleShape.prototype.paintForeground.apply(this, arguments); 2966 var inset = 0; 2967 2968 if (this.isRounded) 2969 { 2970 var f = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, 2971 mxConstants.RECTANGLE_ROUNDING_FACTOR * 100) / 100; 2972 inset = Math.max(inset, Math.min(w * f, h * f)); 2973 } 2974 2975 var dx = Math.max(inset, Math.min(w, parseFloat(mxUtils.getValue(this.style, 'dx', this.dx)))); 2976 var dy = Math.max(inset, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'dy', this.dy)))); 2977 2978 c.begin(); 2979 c.moveTo(x, y + dy); 2980 c.lineTo(x + w, y + dy); 2981 c.end(); 2982 c.stroke(); 2983 2984 c.begin(); 2985 c.moveTo(x + dx, y); 2986 c.lineTo(x + dx, y + h); 2987 c.end(); 2988 c.stroke(); 2989 }; 2990 2991 mxCellRenderer.registerShape('internalStorage', InternalStorageShape); 2992 2993 // Internal storage 2994 function CornerShape() 2995 { 2996 mxActor.call(this); 2997 }; 2998 mxUtils.extend(CornerShape, mxActor); 2999 CornerShape.prototype.dx = 20; 3000 CornerShape.prototype.dy = 20; 3001 3002 // Corner 3003 CornerShape.prototype.redrawPath = function(c, x, y, w, h) 3004 { 3005 var dx = Math.max(0, Math.min(w, parseFloat(mxUtils.getValue(this.style, 'dx', this.dx)))); 3006 var dy = Math.max(0, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'dy', this.dy)))); 3007 3008 var s = Math.min(w / 2, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); 3009 var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2; 3010 this.addPoints(c, [new mxPoint(0, 0), new mxPoint(w, 0), new mxPoint(w, dy), new mxPoint(dx, dy), 3011 new mxPoint(dx, h), new mxPoint(0, h)], this.isRounded, arcSize, true); 3012 c.end(); 3013 }; 3014 3015 mxCellRenderer.registerShape('corner', CornerShape); 3016 3017 // Crossbar shape 3018 function CrossbarShape() 3019 { 3020 mxActor.call(this); 3021 }; 3022 mxUtils.extend(CrossbarShape, mxActor); 3023 3024 CrossbarShape.prototype.redrawPath = function(c, x, y, w, h) 3025 { 3026 c.moveTo(0, 0); 3027 c.lineTo(0, h); 3028 c.end(); 3029 3030 c.moveTo(w, 0); 3031 c.lineTo(w, h); 3032 c.end(); 3033 3034 c.moveTo(0, h / 2); 3035 c.lineTo(w, h / 2); 3036 c.end(); 3037 }; 3038 3039 mxCellRenderer.registerShape('crossbar', CrossbarShape); 3040 3041 // Internal storage 3042 function TeeShape() 3043 { 3044 mxActor.call(this); 3045 }; 3046 mxUtils.extend(TeeShape, mxActor); 3047 TeeShape.prototype.dx = 20; 3048 TeeShape.prototype.dy = 20; 3049 3050 // Corner 3051 TeeShape.prototype.redrawPath = function(c, x, y, w, h) 3052 { 3053 var dx = Math.max(0, Math.min(w, parseFloat(mxUtils.getValue(this.style, 'dx', this.dx)))); 3054 var dy = Math.max(0, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'dy', this.dy)))); 3055 var w2 = Math.abs(w - dx) / 2; 3056 3057 var s = Math.min(w / 2, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); 3058 var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2; 3059 this.addPoints(c, [new mxPoint(0, 0), new mxPoint(w, 0), new mxPoint(w, dy), new mxPoint((w + dx) / 2, dy), 3060 new mxPoint((w + dx) / 2, h), new mxPoint((w - dx) / 2, h), new mxPoint((w - dx) / 2, dy), 3061 new mxPoint(0, dy)], this.isRounded, arcSize, true); 3062 c.end(); 3063 }; 3064 3065 mxCellRenderer.registerShape('tee', TeeShape); 3066 3067 // Arrow 3068 function SingleArrowShape() 3069 { 3070 mxActor.call(this); 3071 }; 3072 mxUtils.extend(SingleArrowShape, mxActor); 3073 SingleArrowShape.prototype.arrowWidth = 0.3; 3074 SingleArrowShape.prototype.arrowSize = 0.2; 3075 SingleArrowShape.prototype.redrawPath = function(c, x, y, w, h) 3076 { 3077 var aw = h * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'arrowWidth', this.arrowWidth)))); 3078 var as = w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'arrowSize', this.arrowSize)))); 3079 var at = (h - aw) / 2; 3080 var ab = at + aw; 3081 3082 var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2; 3083 this.addPoints(c, [new mxPoint(0, at), new mxPoint(w - as, at), new mxPoint(w - as, 0), new mxPoint(w, h / 2), 3084 new mxPoint(w - as, h), new mxPoint(w - as, ab), new mxPoint(0, ab)], 3085 this.isRounded, arcSize, true); 3086 c.end(); 3087 }; 3088 3089 mxCellRenderer.registerShape('singleArrow', SingleArrowShape); 3090 3091 // Arrow 3092 function DoubleArrowShape() 3093 { 3094 mxActor.call(this); 3095 }; 3096 mxUtils.extend(DoubleArrowShape, mxActor); 3097 DoubleArrowShape.prototype.redrawPath = function(c, x, y, w, h) 3098 { 3099 var aw = h * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'arrowWidth', SingleArrowShape.prototype.arrowWidth)))); 3100 var as = w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'arrowSize', SingleArrowShape.prototype.arrowSize)))); 3101 var at = (h - aw) / 2; 3102 var ab = at + aw; 3103 3104 var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2; 3105 this.addPoints(c, [new mxPoint(0, h / 2), new mxPoint(as, 0), new mxPoint(as, at), new mxPoint(w - as, at), 3106 new mxPoint(w - as, 0), new mxPoint(w, h / 2), new mxPoint(w - as, h), 3107 new mxPoint(w - as, ab), new mxPoint(as, ab), new mxPoint(as, h)], 3108 this.isRounded, arcSize, true); 3109 c.end(); 3110 }; 3111 3112 mxCellRenderer.registerShape('doubleArrow', DoubleArrowShape); 3113 3114 // Data storage 3115 function DataStorageShape() 3116 { 3117 mxActor.call(this); 3118 }; 3119 mxUtils.extend(DataStorageShape, mxActor); 3120 DataStorageShape.prototype.size = 0.1; 3121 DataStorageShape.prototype.fixedSize = 20; 3122 DataStorageShape.prototype.redrawPath = function(c, x, y, w, h) 3123 { 3124 var fixed = mxUtils.getValue(this.style, 'fixedSize', '0') != '0'; 3125 var s = (fixed) ? Math.max(0, Math.min(w, parseFloat(mxUtils.getValue(this.style, 'size', this.fixedSize)))) : 3126 w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); 3127 3128 c.moveTo(s, 0); 3129 c.lineTo(w, 0); 3130 c.quadTo(w - s * 2, h / 2, w, h); 3131 c.lineTo(s, h); 3132 c.quadTo(s - s * 2, h / 2, s, 0); 3133 c.close(); 3134 c.end(); 3135 }; 3136 3137 mxCellRenderer.registerShape('dataStorage', DataStorageShape); 3138 3139 // Or 3140 function OrShape() 3141 { 3142 mxActor.call(this); 3143 }; 3144 mxUtils.extend(OrShape, mxActor); 3145 OrShape.prototype.redrawPath = function(c, x, y, w, h) 3146 { 3147 c.moveTo(0, 0); 3148 c.quadTo(w, 0, w, h / 2); 3149 c.quadTo(w, h, 0, h); 3150 c.close(); 3151 c.end(); 3152 }; 3153 3154 mxCellRenderer.registerShape('or', OrShape); 3155 3156 // Xor 3157 function XorShape() 3158 { 3159 mxActor.call(this); 3160 }; 3161 mxUtils.extend(XorShape, mxActor); 3162 XorShape.prototype.redrawPath = function(c, x, y, w, h) 3163 { 3164 c.moveTo(0, 0); 3165 c.quadTo(w, 0, w, h / 2); 3166 c.quadTo(w, h, 0, h); 3167 c.quadTo(w / 2, h / 2, 0, 0); 3168 c.close(); 3169 c.end(); 3170 }; 3171 3172 mxCellRenderer.registerShape('xor', XorShape); 3173 3174 // Loop limit 3175 function LoopLimitShape() 3176 { 3177 mxActor.call(this); 3178 }; 3179 mxUtils.extend(LoopLimitShape, mxActor); 3180 LoopLimitShape.prototype.size = 20; 3181 LoopLimitShape.prototype.isRoundable = function() 3182 { 3183 return true; 3184 }; 3185 LoopLimitShape.prototype.redrawPath = function(c, x, y, w, h) 3186 { 3187 var s = Math.min(w / 2, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); 3188 var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2; 3189 this.addPoints(c, [new mxPoint(s, 0), new mxPoint(w - s, 0), new mxPoint(w, s * 0.8), new mxPoint(w, h), 3190 new mxPoint(0, h), new mxPoint(0, s * 0.8)], this.isRounded, arcSize, true); 3191 c.end(); 3192 }; 3193 3194 mxCellRenderer.registerShape('loopLimit', LoopLimitShape); 3195 3196 // Off page connector 3197 function OffPageConnectorShape() 3198 { 3199 mxActor.call(this); 3200 }; 3201 mxUtils.extend(OffPageConnectorShape, mxActor); 3202 OffPageConnectorShape.prototype.size = 3 / 8; 3203 OffPageConnectorShape.prototype.isRoundable = function() 3204 { 3205 return true; 3206 }; 3207 OffPageConnectorShape.prototype.redrawPath = function(c, x, y, w, h) 3208 { 3209 var s = h * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); 3210 var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2; 3211 this.addPoints(c, [new mxPoint(0, 0), new mxPoint(w, 0), new mxPoint(w, h - s), new mxPoint(w / 2, h), 3212 new mxPoint(0, h - s)], this.isRounded, arcSize, true); 3213 c.end(); 3214 }; 3215 3216 mxCellRenderer.registerShape('offPageConnector', OffPageConnectorShape); 3217 3218 // Internal storage 3219 function TapeDataShape() 3220 { 3221 mxEllipse.call(this); 3222 }; 3223 mxUtils.extend(TapeDataShape, mxEllipse); 3224 TapeDataShape.prototype.paintVertexShape = function(c, x, y, w, h) 3225 { 3226 mxEllipse.prototype.paintVertexShape.apply(this, arguments); 3227 3228 c.begin(); 3229 c.moveTo(x + w / 2, y + h); 3230 c.lineTo(x + w, y + h); 3231 c.end(); 3232 c.stroke(); 3233 }; 3234 3235 mxCellRenderer.registerShape('tapeData', TapeDataShape); 3236 3237 // OrEllipseShape 3238 function OrEllipseShape() 3239 { 3240 mxEllipse.call(this); 3241 }; 3242 mxUtils.extend(OrEllipseShape, mxEllipse); 3243 OrEllipseShape.prototype.paintVertexShape = function(c, x, y, w, h) 3244 { 3245 mxEllipse.prototype.paintVertexShape.apply(this, arguments); 3246 3247 c.setShadow(false); 3248 c.begin(); 3249 c.moveTo(x, y + h / 2); 3250 c.lineTo(x + w, y + h / 2); 3251 c.end(); 3252 c.stroke(); 3253 3254 c.begin(); 3255 c.moveTo(x + w / 2, y); 3256 c.lineTo(x + w / 2, y + h); 3257 c.end(); 3258 c.stroke(); 3259 }; 3260 3261 mxCellRenderer.registerShape('orEllipse', OrEllipseShape); 3262 3263 // SumEllipseShape 3264 function SumEllipseShape() 3265 { 3266 mxEllipse.call(this); 3267 }; 3268 mxUtils.extend(SumEllipseShape, mxEllipse); 3269 SumEllipseShape.prototype.paintVertexShape = function(c, x, y, w, h) 3270 { 3271 mxEllipse.prototype.paintVertexShape.apply(this, arguments); 3272 var s2 = 0.145; 3273 3274 c.setShadow(false); 3275 c.begin(); 3276 c.moveTo(x + w * s2, y + h * s2); 3277 c.lineTo(x + w * (1 - s2), y + h * (1 - s2)); 3278 c.end(); 3279 c.stroke(); 3280 3281 c.begin(); 3282 c.moveTo(x + w * (1 - s2), y + h * s2); 3283 c.lineTo(x + w * s2, y + h * (1 - s2)); 3284 c.end(); 3285 c.stroke(); 3286 }; 3287 3288 mxCellRenderer.registerShape('sumEllipse', SumEllipseShape); 3289 3290 // SortShape 3291 function SortShape() 3292 { 3293 mxRhombus.call(this); 3294 }; 3295 mxUtils.extend(SortShape, mxRhombus); 3296 SortShape.prototype.paintVertexShape = function(c, x, y, w, h) 3297 { 3298 mxRhombus.prototype.paintVertexShape.apply(this, arguments); 3299 3300 c.setShadow(false); 3301 c.begin(); 3302 c.moveTo(x, y + h / 2); 3303 c.lineTo(x + w, y + h / 2); 3304 c.end(); 3305 c.stroke(); 3306 }; 3307 3308 mxCellRenderer.registerShape('sortShape', SortShape); 3309 3310 // CollateShape 3311 function CollateShape() 3312 { 3313 mxEllipse.call(this); 3314 }; 3315 mxUtils.extend(CollateShape, mxEllipse); 3316 CollateShape.prototype.paintVertexShape = function(c, x, y, w, h) 3317 { 3318 c.begin(); 3319 c.moveTo(x, y); 3320 c.lineTo(x + w, y); 3321 c.lineTo(x + w / 2, y + h / 2); 3322 c.close(); 3323 c.fillAndStroke(); 3324 3325 c.begin(); 3326 c.moveTo(x, y + h); 3327 c.lineTo(x + w, y + h); 3328 c.lineTo(x + w / 2, y + h / 2); 3329 c.close(); 3330 c.fillAndStroke(); 3331 }; 3332 3333 mxCellRenderer.registerShape('collate', CollateShape); 3334 3335 // DimensionShape 3336 function DimensionShape() 3337 { 3338 mxEllipse.call(this); 3339 }; 3340 mxUtils.extend(DimensionShape, mxEllipse); 3341 DimensionShape.prototype.paintVertexShape = function(c, x, y, w, h) 3342 { 3343 // Arrow size 3344 var al = 10; 3345 var cy = y + h - al / 2; 3346 3347 c.begin(); 3348 c.moveTo(x, y); 3349 c.lineTo(x, y + h); 3350 c.moveTo(x, cy); 3351 c.lineTo(x + al, cy - al / 2); 3352 c.moveTo(x, cy); 3353 c.lineTo(x + al, cy + al / 2); 3354 c.moveTo(x, cy); 3355 c.lineTo(x + w, cy); 3356 3357 // Opposite side 3358 c.moveTo(x + w, y); 3359 c.lineTo(x + w, y + h); 3360 c.moveTo(x + w, cy); 3361 c.lineTo(x + w - al, cy - al / 2); 3362 c.moveTo(x + w, cy); 3363 c.lineTo(x + w - al, cy + al / 2); 3364 c.end(); 3365 c.stroke(); 3366 }; 3367 3368 mxCellRenderer.registerShape('dimension', DimensionShape); 3369 3370 // PartialRectangleShape 3371 function PartialRectangleShape() 3372 { 3373 mxEllipse.call(this); 3374 }; 3375 mxUtils.extend(PartialRectangleShape, mxEllipse); 3376 PartialRectangleShape.prototype.paintVertexShape = function(c, x, y, w, h) 3377 { 3378 if (!this.outline) 3379 { 3380 c.setStrokeColor(null); 3381 } 3382 3383 if (this.style != null) 3384 { 3385 var pointerEvents = c.pointerEvents; 3386 var events = mxUtils.getValue(this.style, mxConstants.STYLE_POINTER_EVENTS, '1') == '1'; 3387 3388 if (!events && (this.fill == null || this.fill == mxConstants.NONE)) 3389 { 3390 c.pointerEvents = false; 3391 } 3392 3393 c.rect(x, y, w, h); 3394 c.fill(); 3395 3396 c.pointerEvents = pointerEvents; 3397 c.setStrokeColor(this.stroke); 3398 c.begin(); 3399 c.moveTo(x, y); 3400 3401 if (this.outline || mxUtils.getValue(this.style, 'top', '1') == '1') 3402 { 3403 c.lineTo(x + w, y); 3404 } 3405 else 3406 { 3407 c.moveTo(x + w, y); 3408 } 3409 3410 if (this.outline || mxUtils.getValue(this.style, 'right', '1') == '1') 3411 { 3412 c.lineTo(x + w, y + h); 3413 } 3414 else 3415 { 3416 c.moveTo(x + w, y + h); 3417 } 3418 3419 if (this.outline || mxUtils.getValue(this.style, 'bottom', '1') == '1') 3420 { 3421 c.lineTo(x, y + h); 3422 } 3423 else 3424 { 3425 c.moveTo(x, y + h); 3426 } 3427 3428 if (this.outline || mxUtils.getValue(this.style, 'left', '1') == '1') 3429 { 3430 c.lineTo(x, y); 3431 } 3432 3433 c.end(); 3434 c.stroke(); 3435 } 3436 }; 3437 3438 mxCellRenderer.registerShape('partialRectangle', PartialRectangleShape); 3439 3440 // LineEllipseShape 3441 function LineEllipseShape() 3442 { 3443 mxEllipse.call(this); 3444 }; 3445 mxUtils.extend(LineEllipseShape, mxEllipse); 3446 LineEllipseShape.prototype.paintVertexShape = function(c, x, y, w, h) 3447 { 3448 mxEllipse.prototype.paintVertexShape.apply(this, arguments); 3449 3450 c.setShadow(false); 3451 c.begin(); 3452 3453 if (mxUtils.getValue(this.style, 'line') == 'vertical') 3454 { 3455 c.moveTo(x + w / 2, y); 3456 c.lineTo(x + w / 2, y + h); 3457 } 3458 else 3459 { 3460 c.moveTo(x, y + h / 2); 3461 c.lineTo(x + w, y + h / 2); 3462 } 3463 3464 c.end(); 3465 c.stroke(); 3466 }; 3467 3468 mxCellRenderer.registerShape('lineEllipse', LineEllipseShape); 3469 3470 // Delay 3471 function DelayShape() 3472 { 3473 mxActor.call(this); 3474 }; 3475 mxUtils.extend(DelayShape, mxActor); 3476 DelayShape.prototype.redrawPath = function(c, x, y, w, h) 3477 { 3478 var dx = Math.min(w, h / 2); 3479 c.moveTo(0, 0); 3480 c.lineTo(w - dx, 0); 3481 c.quadTo(w, 0, w, h / 2); 3482 c.quadTo(w, h, w - dx, h); 3483 c.lineTo(0, h); 3484 c.close(); 3485 c.end(); 3486 }; 3487 3488 mxCellRenderer.registerShape('delay', DelayShape); 3489 3490 // Cross Shape 3491 function CrossShape() 3492 { 3493 mxActor.call(this); 3494 }; 3495 mxUtils.extend(CrossShape, mxActor); 3496 CrossShape.prototype.size = 0.2; 3497 CrossShape.prototype.redrawPath = function(c, x, y, w, h) 3498 { 3499 var m = Math.min(h, w); 3500 var size = Math.max(0, Math.min(m, m * parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); 3501 var t = (h - size) / 2; 3502 var b = t + size; 3503 var l = (w - size) / 2; 3504 var r = l + size; 3505 3506 c.moveTo(0, t); 3507 c.lineTo(l, t); 3508 c.lineTo(l, 0); 3509 c.lineTo(r, 0); 3510 c.lineTo(r, t); 3511 c.lineTo(w, t); 3512 c.lineTo(w, b); 3513 c.lineTo(r, b); 3514 c.lineTo(r, h); 3515 c.lineTo(l, h); 3516 c.lineTo(l, b); 3517 c.lineTo(0, b); 3518 c.close(); 3519 c.end(); 3520 }; 3521 3522 mxCellRenderer.registerShape('cross', CrossShape); 3523 3524 // Display 3525 function DisplayShape() 3526 { 3527 mxActor.call(this); 3528 }; 3529 mxUtils.extend(DisplayShape, mxActor); 3530 DisplayShape.prototype.size = 0.25; 3531 DisplayShape.prototype.redrawPath = function(c, x, y, w, h) 3532 { 3533 var dx = Math.min(w, h / 2); 3534 var s = Math.min(w - dx, Math.max(0, parseFloat(mxUtils.getValue(this.style, 'size', this.size))) * w); 3535 3536 c.moveTo(0, h / 2); 3537 c.lineTo(s, 0); 3538 c.lineTo(w - dx, 0); 3539 c.quadTo(w, 0, w, h / 2); 3540 c.quadTo(w, h, w - dx, h); 3541 c.lineTo(s, h); 3542 c.close(); 3543 c.end(); 3544 }; 3545 3546 mxCellRenderer.registerShape('display', DisplayShape); 3547 3548 //********************************************************************************************************************************************************** 3549 //Rectangle v2 3550 //********************************************************************************************************************************************************** 3551 /** 3552 * Extends mxShape. 3553 */ 3554 function mxShapeBasicRect2(bounds, fill, stroke, strokewidth) 3555 { 3556 mxShape.call(this); 3557 this.bounds = bounds; 3558 this.fill = fill; 3559 this.stroke = stroke; 3560 this.strokewidth = (strokewidth != null) ? strokewidth : 1; 3561 this.rectStyle = 'square'; 3562 this.size = 10; 3563 this.absoluteCornerSize = true; 3564 this.indent = 2; 3565 this.rectOutline = 'single'; 3566 }; 3567 3568 /** 3569 * Extends mxShape. 3570 */ 3571 mxUtils.extend(mxShapeBasicRect2, mxActor); 3572 3573 mxShapeBasicRect2.prototype.cst = {RECT2 : 'mxgraph.basic.rect'}; 3574 3575 mxShapeBasicRect2.prototype.customProperties = [ 3576 {name: 'rectStyle', dispName: 'Style', type: 'enum', defVal:'square', 3577 enumList:[ 3578 {val:'square', dispName:'Square'}, 3579 {val:'rounded', dispName:'Round'}, 3580 {val:'snip', dispName:'Snip'}, 3581 {val:'invRound', dispName:'Inv. Round'}, 3582 {val:'fold', dispName:'Fold'} 3583 ]}, 3584 {name: 'size', dispName: 'Corner Size', type: 'float', defVal:10}, 3585 {name: 'absoluteCornerSize', dispName: 'Abs. Corner Size', type: 'bool', defVal:true}, 3586 {name: 'indent', dispName:'Indent', type:'float', defVal:2}, 3587 {name: 'rectOutline', dispName: 'Outline', type: 'enum', defVal:'single', 3588 enumList:[ 3589 {val:'single', dispName:'Single'}, 3590 {val:'double', dispName:'Double'}, 3591 {val:'frame', dispName:'Frame'} 3592 ]}, 3593 {name: 'fillColor2', dispName:'Inside Fill Color', type:'color', defVal:'none'}, 3594 {name: 'gradientColor2', dispName:'Inside Gradient Color', type:'color', defVal:'none'}, 3595 {name: 'gradientDirection2', dispName: 'Inside Gradient Direction', type: 'enum', defVal:'south', 3596 enumList:[ 3597 {val:'south', dispName:'South'}, 3598 {val:'west', dispName:'West'}, 3599 {val:'north', dispName:'North'}, 3600 {val:'east', dispName:'East'} 3601 ]}, 3602 {name: 'top', dispName:'Top Line', type:'bool', defVal:true}, 3603 {name: 'right', dispName:'Right', type:'bool', defVal:true}, 3604 {name: 'bottom', dispName:'Bottom Line', type:'bool', defVal:true}, 3605 {name: 'left', dispName:'Left ', type:'bool', defVal:true}, 3606 {name: 'topLeftStyle', dispName: 'Top Left Style', type: 'enum', defVal:'default', 3607 enumList:[ 3608 {val:'default', dispName:'Default'}, 3609 {val:'square', dispName:'Square'}, 3610 {val:'rounded', dispName:'Round'}, 3611 {val:'snip', dispName:'Snip'}, 3612 {val:'invRound', dispName:'Inv. Round'}, 3613 {val:'fold', dispName:'Fold'} 3614 ]}, 3615 {name: 'topRightStyle', dispName: 'Top Right Style', type: 'enum', defVal:'default', 3616 enumList:[ 3617 {val:'default', dispName:'Default'}, 3618 {val:'square', dispName:'Square'}, 3619 {val:'rounded', dispName:'Round'}, 3620 {val:'snip', dispName:'Snip'}, 3621 {val:'invRound', dispName:'Inv. Round'}, 3622 {val:'fold', dispName:'Fold'} 3623 ]}, 3624 {name: 'bottomRightStyle', dispName: 'Bottom Right Style', type: 'enum', defVal:'default', 3625 enumList:[ 3626 {val:'default', dispName:'Default'}, 3627 {val:'square', dispName:'Square'}, 3628 {val:'rounded', dispName:'Round'}, 3629 {val:'snip', dispName:'Snip'}, 3630 {val:'invRound', dispName:'Inv. Round'}, 3631 {val:'fold', dispName:'Fold'} 3632 ]}, 3633 {name: 'bottomLeftStyle', dispName: 'Bottom Left Style', type: 'enum', defVal:'default', 3634 enumList:[ 3635 {val:'default', dispName:'Default'}, 3636 {val:'square', dispName:'Square'}, 3637 {val:'rounded', dispName:'Round'}, 3638 {val:'snip', dispName:'Snip'}, 3639 {val:'invRound', dispName:'Inv. Round'}, 3640 {val:'fold', dispName:'Fold'} 3641 ]}, 3642 ]; 3643 3644 /** 3645 * Function: paintVertexShape 3646 * 3647 * Paints the vertex shape. 3648 */ 3649 mxShapeBasicRect2.prototype.paintVertexShape = function(c, x, y, w, h) 3650 { 3651 c.translate(x, y); 3652 this.strictDrawShape(c, 0, 0, w, h); 3653 } 3654 3655 // 3656 mxShapeBasicRect2.prototype.strictDrawShape = function(c, x, y, w, h, os) 3657 { 3658 // read styles or optionally override them externally via "os" variable 3659 var rectStyle = (os && os.rectStyle) ? os.rectStyle : mxUtils.getValue(this.style, 'rectStyle', this.rectStyle); 3660 var absoluteCornerSize = (os && os.absoluteCornerSize) ? os.absoluteCornerSize : mxUtils.getValue(this.style, 'absoluteCornerSize', this.absoluteCornerSize); 3661 var size = (os && os.size) ? os.size : Math.max(0, Math.min(w, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); 3662 var rectOutline = (os && os.rectOutline) ? os.rectOutline : mxUtils.getValue(this.style, 'rectOutline', this.rectOutline); 3663 var indent = (os && os.indent) ? os.indent : Math.max(0, Math.min(w, parseFloat(mxUtils.getValue(this.style, 'indent', this.indent)))); 3664 var dashed = (os && os.dashed) ? os.dashed : mxUtils.getValue(this.style, 'dashed', false); 3665 var dashPattern = (os && os.dashPattern) ? os.dashPattern : mxUtils.getValue(this.style, 'dashPattern', null); 3666 var relIndent = (os && os.relIndent) ? os.relIndent : Math.max(0, Math.min(50, indent)); 3667 var top = (os && os.top) ? os.top : mxUtils.getValue(this.style, 'top', true); 3668 var right = (os && os.right) ? os.right : mxUtils.getValue(this.style, 'right', true); 3669 var bottom = (os && os.bottom) ? os.bottom : mxUtils.getValue(this.style, 'bottom', true); 3670 var left = (os && os.left) ? os.left : mxUtils.getValue(this.style, 'left', true); 3671 var topLeftStyle = (os && os.topLeftStyle) ? os.topLeftStyle : mxUtils.getValue(this.style, 'topLeftStyle', 'default'); 3672 var topRightStyle = (os && os.topRightStyle) ? os.topRightStyle : mxUtils.getValue(this.style, 'topRightStyle', 'default'); 3673 var bottomRightStyle = (os && os.bottomRightStyle) ? os.bottomRightStyle : mxUtils.getValue(this.style, 'bottomRightStyle', 'default'); 3674 var bottomLeftStyle = (os && os.bottomLeftStyle) ? os.bottomLeftStyle : mxUtils.getValue(this.style, 'bottomLeftStyle', 'default'); 3675 var fillColor = (os && os.fillColor) ? os.fillColor : mxUtils.getValue(this.style, 'fillColor', '#ffffff'); 3676 var strokeColor = (os && os.strokeColor) ? os.strokeColor : mxUtils.getValue(this.style, 'strokeColor', '#000000'); 3677 var strokeWidth = (os && os.strokeWidth) ? os.strokeWidth : mxUtils.getValue(this.style, 'strokeWidth', '1'); 3678 var fillColor2 = (os && os.fillColor2) ? os.fillColor2 : mxUtils.getValue(this.style, 'fillColor2', 'none'); 3679 var gradientColor2 = (os && os.gradientColor2) ? os.gradientColor2 : mxUtils.getValue(this.style, 'gradientColor2', 'none'); 3680 var gdir2 = (os && os.gradientDirection2) ? os.gradientDirection2 : mxUtils.getValue(this.style, 'gradientDirection2', 'south'); 3681 var opacity = (os && os.opacity) ? os.opacity : mxUtils.getValue(this.style, 'opacity', '100'); 3682 3683 var relSize = Math.max(0, Math.min(50, size)); 3684 var sc = mxShapeBasicRect2.prototype; 3685 3686 c.setDashed(dashed); 3687 3688 if (dashPattern && dashPattern != '') 3689 { 3690 c.setDashPattern(dashPattern); 3691 } 3692 3693 c.setStrokeWidth(strokeWidth); 3694 3695 size = Math.min(h * 0.5, w * 0.5, size); 3696 3697 if (!absoluteCornerSize) 3698 { 3699 size = relSize * Math.min(w, h) / 100; 3700 } 3701 3702 size = Math.min(size, Math.min(w, h) * 0.5); 3703 3704 if (!absoluteCornerSize) 3705 { 3706 indent = Math.min(relIndent * Math.min(w, h) / 100); 3707 } 3708 3709 indent = Math.min(indent, Math.min(w, h) * 0.5 - size); 3710 3711 if ((top || right || bottom || left) && rectOutline != 'frame') 3712 { 3713 3714 //outline fill 3715 c.begin(); 3716 if (!top) 3717 { 3718 c.moveTo(0,0); 3719 } 3720 else 3721 { 3722 sc.moveNW(c, x, y, w, h, rectStyle, topLeftStyle, size, left); 3723 } 3724 3725 if (top) 3726 { 3727 sc.paintNW(c, x, y, w, h, rectStyle, topLeftStyle, size, left); 3728 } 3729 3730 sc.paintTop(c, x, y, w, h, rectStyle, topRightStyle, size, right); 3731 3732 if (right) 3733 { 3734 sc.paintNE(c, x, y, w, h, rectStyle, topRightStyle, size, top); 3735 } 3736 3737 sc.paintRight(c, x, y, w, h, rectStyle, bottomRightStyle, size, bottom); 3738 3739 if (bottom) 3740 { 3741 sc.paintSE(c, x, y, w, h, rectStyle, bottomRightStyle, size, right); 3742 } 3743 3744 sc.paintBottom(c, x, y, w, h, rectStyle, bottomLeftStyle, size, left); 3745 3746 if (left) 3747 { 3748 sc.paintSW(c, x, y, w, h, rectStyle, bottomLeftStyle, size, bottom); 3749 } 3750 3751 sc.paintLeft(c, x, y, w, h, rectStyle, topLeftStyle, size, top); 3752 c.close(); 3753 c.fill(); 3754 3755 c.setShadow(false); 3756 3757 //inner fill 3758 c.setFillColor(fillColor2); 3759 var op1 = opacity; 3760 var op2 = opacity; 3761 3762 if (fillColor2 == 'none') 3763 { 3764 op1 = 0; 3765 } 3766 3767 if (gradientColor2 == 'none') 3768 { 3769 op2 = 0; 3770 } 3771 3772 c.setGradient(fillColor2, gradientColor2, 0, 0, w, h, gdir2, op1, op2); 3773 3774 c.begin(); 3775 3776 if (!top) 3777 { 3778 c.moveTo(indent,0); 3779 } 3780 else 3781 { 3782 sc.moveNWInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, top, left); 3783 } 3784 3785 sc.paintLeftInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom, left); 3786 3787 if (left && bottom) 3788 { 3789 sc.paintSWInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom); 3790 } 3791 3792 sc.paintBottomInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, right, bottom); 3793 3794 if (bottom && right) 3795 { 3796 sc.paintSEInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent); 3797 } 3798 3799 sc.paintRightInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent, top, right); 3800 3801 if (right && top) 3802 { 3803 sc.paintNEInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent); 3804 } 3805 3806 sc.paintTopInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, left, top); 3807 3808 if (top && left) 3809 { 3810 sc.paintNWInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent); 3811 } 3812 3813 c.fill(); 3814 3815 if (fillColor == 'none') 3816 { 3817 c.begin(); 3818 sc.paintFolds(c, x, y, w, h, rectStyle, topLeftStyle, topRightStyle, bottomRightStyle, bottomLeftStyle, size, top, right, bottom, left); 3819 c.stroke(); 3820 } 3821 } 3822 3823 //draw all the combinations 3824 if (!top && !right && !bottom && left) 3825 { 3826 3827 if (rectOutline != 'frame') 3828 { 3829 c.begin(); 3830 sc.moveSW(c, x, y, w, h, rectStyle, topLeftStyle, size, bottom); 3831 sc.paintLeft(c, x, y, w, h, rectStyle, topLeftStyle, size, top); 3832 3833 if (rectOutline == 'double') 3834 { 3835 sc.moveNWInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, top, left); 3836 sc.paintLeftInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom, left); 3837 } 3838 3839 c.stroke(); 3840 } 3841 else 3842 { 3843 c.begin(); 3844 sc.moveSW(c, x, y, w, h, rectStyle, topLeftStyle, size, bottom); 3845 sc.paintLeft(c, x, y, w, h, rectStyle, topLeftStyle, size, top); 3846 sc.lineNWInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, top, left); 3847 sc.paintLeftInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom, left); 3848 c.close(); 3849 c.fillAndStroke(); 3850 } 3851 } 3852 else if (!top && !right && bottom && !left) 3853 { 3854 if (rectOutline != 'frame') 3855 { 3856 c.begin(); 3857 sc.moveSE(c, x, y, w, h, rectStyle, bottomRightStyle, size, right); 3858 sc.paintBottom(c, x, y, w, h, rectStyle, bottomLeftStyle, size, left); 3859 3860 if (rectOutline == 'double') 3861 { 3862 sc.moveSWInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, left); 3863 sc.paintBottomInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, right, bottom); 3864 } 3865 3866 c.stroke(); 3867 } 3868 else 3869 { 3870 c.begin(); 3871 sc.moveSE(c, x, y, w, h, rectStyle, bottomRightStyle, size, right); 3872 sc.paintBottom(c, x, y, w, h, rectStyle, bottomLeftStyle, size, left); 3873 sc.lineSWInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, left); 3874 sc.paintBottomInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, right, bottom); 3875 c.close(); 3876 c.fillAndStroke(); 3877 } 3878 } 3879 else if (!top && !right && bottom && left) 3880 { 3881 if (rectOutline != 'frame') 3882 { 3883 c.begin(); 3884 sc.moveSE(c, x, y, w, h, rectStyle, bottomRightStyle, size, right); 3885 sc.paintBottom(c, x, y, w, h, rectStyle, bottomLeftStyle, size, left); 3886 sc.paintSW(c, x, y, w, h, rectStyle, bottomLeftStyle, size, bottom); 3887 sc.paintLeft(c, x, y, w, h, rectStyle, topLeftStyle, size, top); 3888 3889 if (rectOutline == 'double') 3890 { 3891 sc.moveNWInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, top, left); 3892 sc.paintLeftInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom, left); 3893 sc.paintSWInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom); 3894 sc.paintBottomInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, right, bottom); 3895 } 3896 3897 c.stroke(); 3898 } 3899 else 3900 { 3901 c.begin(); 3902 sc.moveSE(c, x, y, w, h, rectStyle, bottomRightStyle, size, right); 3903 sc.paintBottom(c, x, y, w, h, rectStyle, bottomLeftStyle, size, left); 3904 sc.paintSW(c, x, y, w, h, rectStyle, bottomLeftStyle, size, bottom); 3905 sc.paintLeft(c, x, y, w, h, rectStyle, topLeftStyle, size, top); 3906 sc.lineNWInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, top, left); 3907 sc.paintLeftInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom, left); 3908 sc.paintSWInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom); 3909 sc.paintBottomInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, right, bottom); 3910 c.close(); 3911 c.fillAndStroke(); 3912 } 3913 } 3914 else if (!top && right && !bottom && !left) 3915 { 3916 if (rectOutline != 'frame') 3917 { 3918 c.begin(); 3919 sc.moveNE(c, x, y, w, h, rectStyle, topRightStyle, size, top); 3920 sc.paintRight(c, x, y, w, h, rectStyle, bottomRightStyle, size, bottom); 3921 3922 if (rectOutline == 'double') 3923 { 3924 sc.moveSEInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, bottom); 3925 sc.paintRightInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent, top, right); 3926 } 3927 3928 c.stroke(); 3929 } 3930 else 3931 { 3932 c.begin(); 3933 sc.moveNE(c, x, y, w, h, rectStyle, topRightStyle, size, top); 3934 sc.paintRight(c, x, y, w, h, rectStyle, bottomRightStyle, size, bottom); 3935 sc.lineSEInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, bottom); 3936 sc.paintRightInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent, top, right); 3937 c.close(); 3938 c.fillAndStroke(); 3939 } 3940 } 3941 else if (!top && right && !bottom && left) 3942 { 3943 if (rectOutline != 'frame') 3944 { 3945 c.begin(); 3946 sc.moveSW(c, x, y, w, h, rectStyle, topLeftStyle, size, bottom); 3947 sc.paintLeft(c, x, y, w, h, rectStyle, topLeftStyle, size, top); 3948 3949 if (rectOutline == 'double') 3950 { 3951 sc.moveNWInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, top, left); 3952 sc.paintLeftInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom, left); 3953 } 3954 3955 c.stroke(); 3956 3957 c.begin(); 3958 sc.moveNE(c, x, y, w, h, rectStyle, topRightStyle, size, top); 3959 sc.paintRight(c, x, y, w, h, rectStyle, bottomRightStyle, size, bottom); 3960 3961 if (rectOutline == 'double') 3962 { 3963 sc.moveSEInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, bottom); 3964 sc.paintRightInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent, top, right); 3965 } 3966 3967 c.stroke(); 3968 } 3969 else 3970 { 3971 c.begin(); 3972 sc.moveSW(c, x, y, w, h, rectStyle, topLeftStyle, size, bottom); 3973 sc.paintLeft(c, x, y, w, h, rectStyle, topLeftStyle, size, top); 3974 sc.lineNWInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, top, left); 3975 sc.paintLeftInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom, left); 3976 c.close(); 3977 c.fillAndStroke(); 3978 3979 c.begin(); 3980 sc.moveNE(c, x, y, w, h, rectStyle, topRightStyle, size, top); 3981 sc.paintRight(c, x, y, w, h, rectStyle, bottomRightStyle, size, bottom); 3982 sc.lineSEInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, bottom); 3983 sc.paintRightInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent, top, right); 3984 c.close(); 3985 c.fillAndStroke(); 3986 } 3987 } 3988 else if (!top && right && bottom && !left) 3989 { 3990 if (rectOutline != 'frame') 3991 { 3992 c.begin(); 3993 sc.moveNE(c, x, y, w, h, rectStyle, topRightStyle, size, top); 3994 sc.paintRight(c, x, y, w, h, rectStyle, bottomRightStyle, size, bottom); 3995 sc.paintSE(c, x, y, w, h, rectStyle, bottomRightStyle, size, right); 3996 sc.paintBottom(c, x, y, w, h, rectStyle, bottomLeftStyle, size, left); 3997 3998 if (rectOutline == 'double') 3999 { 4000 sc.moveSWInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, left); 4001 sc.paintBottomInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, right, bottom); 4002 sc.paintSEInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent); 4003 sc.paintRightInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent, top, right); 4004 } 4005 4006 c.stroke(); 4007 } 4008 else 4009 { 4010 c.begin(); 4011 sc.moveNE(c, x, y, w, h, rectStyle, topRightStyle, size, top); 4012 sc.paintRight(c, x, y, w, h, rectStyle, bottomRightStyle, size, bottom); 4013 sc.paintSE(c, x, y, w, h, rectStyle, bottomRightStyle, size, right); 4014 sc.paintBottom(c, x, y, w, h, rectStyle, bottomLeftStyle, size, left); 4015 sc.lineSWInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, left); 4016 sc.paintBottomInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, right, bottom); 4017 sc.paintSEInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent); 4018 sc.paintRightInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent, top, right); 4019 c.close(); 4020 c.fillAndStroke(); 4021 } 4022 } 4023 else if (!top && right && bottom && left) 4024 { 4025 if (rectOutline != 'frame') 4026 { 4027 c.begin(); 4028 sc.moveNE(c, x, y, w, h, rectStyle, topRightStyle, size, top); 4029 sc.paintRight(c, x, y, w, h, rectStyle, bottomRightStyle, size, bottom); 4030 sc.paintSE(c, x, y, w, h, rectStyle, bottomRightStyle, size, right); 4031 sc.paintBottom(c, x, y, w, h, rectStyle, bottomLeftStyle, size, left); 4032 sc.paintSW(c, x, y, w, h, rectStyle, bottomLeftStyle, size, bottom); 4033 sc.paintLeft(c, x, y, w, h, rectStyle, topLeftStyle, size, top); 4034 4035 if (rectOutline == 'double') 4036 { 4037 sc.moveNWInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, top, left); 4038 sc.paintLeftInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom, left); 4039 sc.paintSWInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom); 4040 sc.paintBottomInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, right, bottom); 4041 sc.paintSEInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent); 4042 sc.paintRightInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent, top, right); 4043 } 4044 4045 c.stroke(); 4046 } 4047 else 4048 { 4049 c.begin(); 4050 sc.moveNE(c, x, y, w, h, rectStyle, topRightStyle, size, top); 4051 sc.paintRight(c, x, y, w, h, rectStyle, bottomRightStyle, size, bottom); 4052 sc.paintSE(c, x, y, w, h, rectStyle, bottomRightStyle, size, right); 4053 sc.paintBottom(c, x, y, w, h, rectStyle, bottomLeftStyle, size, left); 4054 sc.paintSW(c, x, y, w, h, rectStyle, bottomLeftStyle, size, bottom); 4055 sc.paintLeft(c, x, y, w, h, rectStyle, topLeftStyle, size, top); 4056 sc.lineNWInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, top, left); 4057 sc.paintLeftInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom, left); 4058 sc.paintSWInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom); 4059 sc.paintBottomInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, right, bottom); 4060 sc.paintSEInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent); 4061 sc.paintRightInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent, top, right); 4062 c.close(); 4063 c.fillAndStroke(); 4064 } 4065 } 4066 else if (top && !right && !bottom && !left) 4067 { 4068 if (rectOutline != 'frame') 4069 { 4070 c.begin(); 4071 sc.moveNW(c, x, y, w, h, rectStyle, topLeftStyle, size, left); 4072 sc.paintTop(c, x, y, w, h, rectStyle, topRightStyle, size, right); 4073 4074 if (rectOutline == 'double') 4075 { 4076 sc.moveNEInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent, right); 4077 sc.paintTopInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, left, top); 4078 } 4079 4080 c.stroke(); 4081 } 4082 else 4083 { 4084 c.begin(); 4085 sc.moveNW(c, x, y, w, h, rectStyle, topLeftStyle, size, left); 4086 sc.paintTop(c, x, y, w, h, rectStyle, topRightStyle, size, right); 4087 sc.lineNEInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent, right); 4088 sc.paintTopInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, left, top); 4089 c.close(); 4090 c.fillAndStroke(); 4091 } 4092 } 4093 else if (top && !right && !bottom && left) 4094 { 4095 if (rectOutline != 'frame') 4096 { 4097 c.begin(); 4098 sc.moveSW(c, x, y, w, h, rectStyle, bottomLeftStyle, size, bottom); 4099 sc.paintLeft(c, x, y, w, h, rectStyle, topLeftStyle, size, top); 4100 sc.paintNW(c, x, y, w, h, rectStyle, topLeftStyle, size, left); 4101 sc.paintTop(c, x, y, w, h, rectStyle, topRightStyle, size, right); 4102 4103 if (rectOutline == 'double') 4104 { 4105 sc.moveNEInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent, right); 4106 sc.paintTopInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, left, top); 4107 sc.paintNWInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent); 4108 sc.paintLeftInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom, left); 4109 } 4110 4111 c.stroke(); 4112 } 4113 else 4114 { 4115 c.begin(); 4116 sc.moveSW(c, x, y, w, h, rectStyle, bottomLeftStyle, size, bottom); 4117 sc.paintLeft(c, x, y, w, h, rectStyle, topLeftStyle, size, top); 4118 sc.paintNW(c, x, y, w, h, rectStyle, topLeftStyle, size, left); 4119 sc.paintTop(c, x, y, w, h, rectStyle, topRightStyle, size, right); 4120 sc.lineNEInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent, right); 4121 sc.paintTopInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, left, top); 4122 sc.paintNWInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent); 4123 sc.paintLeftInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom, left); 4124 c.close(); 4125 c.fillAndStroke(); 4126 } 4127 } 4128 else if (top && !right && bottom && !left) 4129 { 4130 if (rectOutline != 'frame') 4131 { 4132 c.begin(); 4133 sc.moveNW(c, x, y, w, h, rectStyle, topLeftStyle, size, left); 4134 sc.paintTop(c, x, y, w, h, rectStyle, topRightStyle, size, right); 4135 4136 if (rectOutline == 'double') 4137 { 4138 sc.moveNEInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent, right); 4139 sc.paintTopInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, left, top); 4140 } 4141 4142 c.stroke(); 4143 4144 c.begin(); 4145 sc.moveSE(c, x, y, w, h, rectStyle, bottomRightStyle, size, right); 4146 sc.paintBottom(c, x, y, w, h, rectStyle, bottomLeftStyle, size, left); 4147 4148 if (rectOutline == 'double') 4149 { 4150 sc.moveSWInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, left); 4151 sc.paintBottomInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, right, bottom); 4152 } 4153 4154 c.stroke(); 4155 } 4156 else 4157 { 4158 c.begin(); 4159 sc.moveNW(c, x, y, w, h, rectStyle, topLeftStyle, size, left); 4160 sc.paintTop(c, x, y, w, h, rectStyle, topRightStyle, size, right); 4161 sc.lineNEInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent, right); 4162 sc.paintTopInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, left, top); 4163 c.close(); 4164 c.fillAndStroke(); 4165 4166 c.begin(); 4167 sc.moveSE(c, x, y, w, h, rectStyle, bottomRightStyle, size, right); 4168 sc.paintBottom(c, x, y, w, h, rectStyle, bottomLeftStyle, size, left); 4169 sc.lineSWInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, left); 4170 sc.paintBottomInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, right, bottom); 4171 c.close(); 4172 c.fillAndStroke(); 4173 } 4174 } 4175 else if (top && !right && bottom && left) 4176 { 4177 if (rectOutline != 'frame') 4178 { 4179 c.begin(); 4180 sc.moveSE(c, x, y, w, h, rectStyle, bottomRightStyle, size, right); 4181 sc.paintBottom(c, x, y, w, h, rectStyle, bottomLeftStyle, size, left); 4182 sc.paintSW(c, x, y, w, h, rectStyle, bottomLeftStyle, size, bottom); 4183 sc.paintLeft(c, x, y, w, h, rectStyle, topLeftStyle, size, top); 4184 sc.paintNW(c, x, y, w, h, rectStyle, topLeftStyle, size, left); 4185 sc.paintTop(c, x, y, w, h, rectStyle, topRightStyle, size, right); 4186 4187 if (rectOutline == 'double') 4188 { 4189 sc.moveNEInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent, right); 4190 sc.paintTopInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, left, top); 4191 sc.paintNWInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent); 4192 sc.paintLeftInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom, left); 4193 sc.paintSWInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom); 4194 sc.paintBottomInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, right, bottom); 4195 } 4196 4197 c.stroke(); 4198 } 4199 else 4200 { 4201 c.begin(); 4202 sc.moveSE(c, x, y, w, h, rectStyle, bottomRightStyle, size, right); 4203 sc.paintBottom(c, x, y, w, h, rectStyle, bottomLeftStyle, size, left); 4204 sc.paintSW(c, x, y, w, h, rectStyle, bottomLeftStyle, size, bottom); 4205 sc.paintLeft(c, x, y, w, h, rectStyle, topLeftStyle, size, top); 4206 sc.paintNW(c, x, y, w, h, rectStyle, topLeftStyle, size, left); 4207 sc.paintTop(c, x, y, w, h, rectStyle, topRightStyle, size, right); 4208 sc.lineNEInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent, right); 4209 sc.paintTopInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, left, top); 4210 sc.paintNWInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent); 4211 sc.paintLeftInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom, left); 4212 sc.paintSWInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom); 4213 sc.paintBottomInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, right, bottom); 4214 c.close(); 4215 c.fillAndStroke(); 4216 } 4217 } 4218 else if (top && right && !bottom && !left) 4219 { 4220 if (rectOutline != 'frame') 4221 { 4222 c.begin(); 4223 sc.moveNW(c, x, y, w, h, rectStyle, topLeftStyle, size, left); 4224 sc.paintTop(c, x, y, w, h, rectStyle, topRightStyle, size, right); 4225 sc.paintNE(c, x, y, w, h, rectStyle, topRightStyle, size, top); 4226 sc.paintRight(c, x, y, w, h, rectStyle, bottomRightStyle, size, bottom); 4227 4228 if (rectOutline == 'double') 4229 { 4230 sc.moveSEInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, bottom); 4231 sc.paintRightInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent, top, right); 4232 sc.paintNEInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent); 4233 sc.paintTopInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, left, top); 4234 } 4235 4236 c.stroke(); 4237 } 4238 else 4239 { 4240 c.begin(); 4241 sc.moveNW(c, x, y, w, h, rectStyle, topLeftStyle, size, left); 4242 sc.paintTop(c, x, y, w, h, rectStyle, topRightStyle, size, right); 4243 sc.paintNE(c, x, y, w, h, rectStyle, topRightStyle, size, top); 4244 sc.paintRight(c, x, y, w, h, rectStyle, bottomRightStyle, size, bottom); 4245 sc.lineSEInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, bottom); 4246 sc.paintRightInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent, top, right); 4247 sc.paintNEInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent); 4248 sc.paintTopInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, left, top); 4249 c.close(); 4250 c.fillAndStroke(); 4251 } 4252 } 4253 else if (top && right && !bottom && left) 4254 { 4255 if (rectOutline != 'frame') 4256 { 4257 c.begin(); 4258 sc.moveSW(c, x, y, w, h, rectStyle, bottomLeftStyle, size, bottom); 4259 sc.paintLeft(c, x, y, w, h, rectStyle, topLeftStyle, size, top); 4260 sc.paintNW(c, x, y, w, h, rectStyle, topLeftStyle, size, left); 4261 sc.paintTop(c, x, y, w, h, rectStyle, topRightStyle, size, right); 4262 sc.paintNE(c, x, y, w, h, rectStyle, topRightStyle, size, top); 4263 sc.paintRight(c, x, y, w, h, rectStyle, bottomRightStyle, size, bottom); 4264 4265 if (rectOutline == 'double') 4266 { 4267 sc.moveSEInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, bottom); 4268 sc.paintRightInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent, top, right); 4269 sc.paintNEInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent); 4270 sc.paintTopInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, left, top); 4271 sc.paintNWInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent); 4272 sc.paintLeftInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom, left); 4273 } 4274 4275 c.stroke(); 4276 } 4277 else 4278 { 4279 c.begin(); 4280 sc.moveSW(c, x, y, w, h, rectStyle, bottomLeftStyle, size, bottom); 4281 sc.paintLeft(c, x, y, w, h, rectStyle, topLeftStyle, size, top); 4282 sc.paintNW(c, x, y, w, h, rectStyle, topLeftStyle, size, left); 4283 sc.paintTop(c, x, y, w, h, rectStyle, topRightStyle, size, right); 4284 sc.paintNE(c, x, y, w, h, rectStyle, topRightStyle, size, top); 4285 sc.paintRight(c, x, y, w, h, rectStyle, bottomRightStyle, size, bottom); 4286 sc.lineSEInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, bottom); 4287 sc.paintRightInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent, top, right); 4288 sc.paintNEInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent); 4289 sc.paintTopInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, left, top); 4290 sc.paintNWInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent); 4291 sc.paintLeftInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom, left); 4292 c.close(); 4293 c.fillAndStroke(); 4294 } 4295 } 4296 else if (top && right && bottom && !left) 4297 { 4298 if (rectOutline != 'frame') 4299 { 4300 c.begin(); 4301 sc.moveNW(c, x, y, w, h, rectStyle, topLeftStyle, size, left); 4302 sc.paintTop(c, x, y, w, h, rectStyle, topRightStyle, size, right); 4303 sc.paintNE(c, x, y, w, h, rectStyle, topRightStyle, size, top); 4304 sc.paintRight(c, x, y, w, h, rectStyle, bottomRightStyle, size, bottom); 4305 sc.paintSE(c, x, y, w, h, rectStyle, bottomRightStyle, size, right); 4306 sc.paintBottom(c, x, y, w, h, rectStyle, bottomLeftStyle, size, left); 4307 4308 if (rectOutline == 'double') 4309 { 4310 sc.moveSWInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, left); 4311 sc.paintBottomInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, right, bottom); 4312 sc.paintSEInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent); 4313 sc.paintRightInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent, top, right); 4314 sc.paintNEInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent); 4315 sc.paintTopInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, left, top); 4316 } 4317 4318 c.stroke(); 4319 } 4320 else 4321 { 4322 c.begin(); 4323 sc.moveNW(c, x, y, w, h, rectStyle, topLeftStyle, size, left); 4324 sc.paintTop(c, x, y, w, h, rectStyle, topRightStyle, size, right); 4325 sc.paintNE(c, x, y, w, h, rectStyle, topRightStyle, size, top); 4326 sc.paintRight(c, x, y, w, h, rectStyle, bottomRightStyle, size, bottom); 4327 sc.paintSE(c, x, y, w, h, rectStyle, bottomRightStyle, size, right); 4328 sc.paintBottom(c, x, y, w, h, rectStyle, bottomLeftStyle, size, left); 4329 sc.lineSWInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, left); 4330 sc.paintBottomInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, right, bottom); 4331 sc.paintSEInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent); 4332 sc.paintRightInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent, top, right); 4333 sc.paintNEInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent); 4334 sc.paintTopInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, left, top); 4335 c.close(); 4336 c.fillAndStroke(); 4337 } 4338 } 4339 else if (top && right && bottom && left) 4340 { 4341 if (rectOutline != 'frame') 4342 { 4343 c.begin(); 4344 sc.moveNW(c, x, y, w, h, rectStyle, topLeftStyle, size, left); 4345 sc.paintNW(c, x, y, w, h, rectStyle, topLeftStyle, size, left); 4346 sc.paintTop(c, x, y, w, h, rectStyle, topRightStyle, size, right); 4347 sc.paintNE(c, x, y, w, h, rectStyle, topRightStyle, size, top); 4348 sc.paintRight(c, x, y, w, h, rectStyle, bottomRightStyle, size, bottom); 4349 sc.paintSE(c, x, y, w, h, rectStyle, bottomRightStyle, size, right); 4350 sc.paintBottom(c, x, y, w, h, rectStyle, bottomLeftStyle, size, left); 4351 sc.paintSW(c, x, y, w, h, rectStyle, bottomLeftStyle, size, bottom); 4352 sc.paintLeft(c, x, y, w, h, rectStyle, topLeftStyle, size, top); 4353 c.close(); 4354 4355 if (rectOutline == 'double') 4356 { 4357 sc.moveSWInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, left); 4358 sc.paintSWInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom); 4359 sc.paintBottomInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, right, bottom); 4360 sc.paintSEInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent); 4361 sc.paintRightInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent, top, right); 4362 sc.paintNEInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent); 4363 sc.paintTopInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, left, top); 4364 sc.paintNWInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent); 4365 sc.paintLeftInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom, left); 4366 c.close(); 4367 } 4368 4369 c.stroke(); 4370 } 4371 else 4372 { 4373 c.begin(); 4374 sc.moveNW(c, x, y, w, h, rectStyle, topLeftStyle, size, left); 4375 sc.paintNW(c, x, y, w, h, rectStyle, topLeftStyle, size, left); 4376 sc.paintTop(c, x, y, w, h, rectStyle, topRightStyle, size, right); 4377 sc.paintNE(c, x, y, w, h, rectStyle, topRightStyle, size, top); 4378 sc.paintRight(c, x, y, w, h, rectStyle, bottomRightStyle, size, bottom); 4379 sc.paintSE(c, x, y, w, h, rectStyle, bottomRightStyle, size, right); 4380 sc.paintBottom(c, x, y, w, h, rectStyle, bottomLeftStyle, size, left); 4381 sc.paintSW(c, x, y, w, h, rectStyle, bottomLeftStyle, size, bottom); 4382 sc.paintLeft(c, x, y, w, h, rectStyle, topLeftStyle, size, top); 4383 c.close(); 4384 sc.moveSWInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, left); 4385 sc.paintSWInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom); 4386 sc.paintBottomInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, right, bottom); 4387 sc.paintSEInner(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent); 4388 sc.paintRightInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent, top, right); 4389 sc.paintNEInner(c, x, y, w, h, rectStyle, topRightStyle, size, indent); 4390 sc.paintTopInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, left, top); 4391 sc.paintNWInner(c, x, y, w, h, rectStyle, topLeftStyle, size, indent); 4392 sc.paintLeftInner(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom, left); 4393 c.close(); 4394 c.fillAndStroke(); 4395 } 4396 } 4397 4398 c.begin(); 4399 sc.paintFolds(c, x, y, w, h, rectStyle, topLeftStyle, topRightStyle, bottomRightStyle, bottomLeftStyle, size, top, right, bottom, left); 4400 c.stroke(); 4401 }; 4402 4403 mxShapeBasicRect2.prototype.moveNW = function(c, x, y, w, h, rectStyle, topLeftStyle, size, left) 4404 { 4405 if((topLeftStyle == 'square' || (topLeftStyle == 'default' && rectStyle == 'square' )) || !left) 4406 { 4407 c.moveTo(0, 0); 4408 } 4409 else 4410 { 4411 c.moveTo(0, size); 4412 } 4413 }; 4414 4415 mxShapeBasicRect2.prototype.moveNE = function(c, x, y, w, h, rectStyle, topRightStyle, size, top) 4416 { 4417 if((topRightStyle == 'square' || (topRightStyle == 'default' && rectStyle == 'square' )) || !top) 4418 { 4419 c.moveTo(w, 0); 4420 } 4421 else 4422 { 4423 c.moveTo(w - size, 0); 4424 } 4425 }; 4426 4427 mxShapeBasicRect2.prototype.moveSE = function(c, x, y, w, h, rectStyle, bottomRightStyle, size, right) 4428 { 4429 if((bottomRightStyle == 'square' || (bottomRightStyle == 'default' && rectStyle == 'square' )) || !right) 4430 { 4431 c.moveTo(w, h); 4432 } 4433 else 4434 { 4435 c.moveTo(w, h - size); 4436 } 4437 }; 4438 4439 mxShapeBasicRect2.prototype.moveSW = function(c, x, y, w, h, rectStyle, bottomLeftStyle, size, bottom) 4440 { 4441 if((bottomLeftStyle == 'square' || (bottomLeftStyle == 'default' && rectStyle == 'square' )) || !bottom) 4442 { 4443 c.moveTo(0, h); 4444 } 4445 else 4446 { 4447 c.moveTo(size, h); 4448 } 4449 }; 4450 4451 mxShapeBasicRect2.prototype.paintNW = function(c, x, y, w, h, rectStyle, topLeftStyle, size, left) 4452 { 4453 if (!left) 4454 { 4455 c.lineTo(0, 0); 4456 } 4457 else if((topLeftStyle == 'rounded' || (topLeftStyle == 'default' && rectStyle == 'rounded' )) || 4458 (topLeftStyle == 'invRound' || (topLeftStyle == 'default' && rectStyle == 'invRound' )) ) 4459 { 4460 var inv = 0; 4461 4462 if (topLeftStyle == 'rounded' || (topLeftStyle == 'default' && rectStyle == 'rounded' )) 4463 { 4464 inv = 1; 4465 } 4466 4467 c.arcTo(size, size, 0, 0, inv, size, 0); 4468 } 4469 else if((topLeftStyle == 'snip' || (topLeftStyle == 'default' && rectStyle == 'snip' )) || 4470 (topLeftStyle == 'fold' || (topLeftStyle == 'default' && rectStyle == 'fold' ))) 4471 { 4472 c.lineTo(size, 0); 4473 } 4474 }; 4475 4476 mxShapeBasicRect2.prototype.paintTop = function(c, x, y, w, h, rectStyle, topRightStyle, size, right) 4477 { 4478 if((topRightStyle == 'square' || (topRightStyle == 'default' && rectStyle == 'square' )) || !right) 4479 { 4480 c.lineTo(w, 0); 4481 } 4482 else 4483 { 4484 c.lineTo(w - size, 0); 4485 } 4486 }; 4487 4488 mxShapeBasicRect2.prototype.paintNE = function(c, x, y, w, h, rectStyle, topRightStyle, size, top) 4489 { 4490 if (!top) 4491 { 4492 c.lineTo(w, 0); 4493 } 4494 else if((topRightStyle == 'rounded' || (topRightStyle == 'default' && rectStyle == 'rounded' )) || 4495 (topRightStyle == 'invRound' || (topRightStyle == 'default' && rectStyle == 'invRound' )) ) 4496 { 4497 var inv = 0; 4498 4499 if (topRightStyle == 'rounded' || (topRightStyle == 'default' && rectStyle == 'rounded' )) 4500 { 4501 inv = 1; 4502 } 4503 4504 c.arcTo(size, size, 0, 0, inv, w, size); 4505 } 4506 else if((topRightStyle == 'snip' || (topRightStyle == 'default' && rectStyle == 'snip' )) || 4507 (topRightStyle == 'fold' || (topRightStyle == 'default' && rectStyle == 'fold' ))) 4508 { 4509 c.lineTo(w, size); 4510 } 4511 }; 4512 4513 mxShapeBasicRect2.prototype.paintRight = function(c, x, y, w, h, rectStyle, bottomRightStyle, size, bottom) 4514 { 4515 if((bottomRightStyle == 'square' || (bottomRightStyle == 'default' && rectStyle == 'square' )) || !bottom) 4516 { 4517 c.lineTo(w, h); 4518 } 4519 else 4520 { 4521 c.lineTo(w, h - size); 4522 } 4523 }; 4524 4525 mxShapeBasicRect2.prototype.paintLeft = function(c, x, y, w, h, rectStyle, topLeftStyle, size, top) 4526 { 4527 if((topLeftStyle == 'square' || (topLeftStyle == 'default' && rectStyle == 'square' )) || !top) 4528 { 4529 c.lineTo(0, 0); 4530 } 4531 else 4532 { 4533 c.lineTo(0, size); 4534 } 4535 }; 4536 4537 mxShapeBasicRect2.prototype.paintSE = function(c, x, y, w, h, rectStyle, bottomRightStyle, size, right) 4538 { 4539 if (!right) 4540 { 4541 c.lineTo(w, h); 4542 } 4543 else if((bottomRightStyle == 'rounded' || (bottomRightStyle == 'default' && rectStyle == 'rounded' )) || 4544 (bottomRightStyle == 'invRound' || (bottomRightStyle == 'default' && rectStyle == 'invRound' )) ) 4545 { 4546 var inv = 0; 4547 4548 if (bottomRightStyle == 'rounded' || (bottomRightStyle == 'default' && rectStyle == 'rounded' )) 4549 { 4550 inv = 1; 4551 } 4552 4553 c.arcTo(size, size, 0, 0, inv, w - size, h); 4554 } 4555 else if((bottomRightStyle == 'snip' || (bottomRightStyle == 'default' && rectStyle == 'snip' )) || 4556 (bottomRightStyle == 'fold' || (bottomRightStyle == 'default' && rectStyle == 'fold' ))) 4557 { 4558 c.lineTo(w - size, h); 4559 } 4560 }; 4561 4562 mxShapeBasicRect2.prototype.paintBottom = function(c, x, y, w, h, rectStyle, bottomLeftStyle, size, left) 4563 { 4564 if((bottomLeftStyle == 'square' || (bottomLeftStyle == 'default' && rectStyle == 'square' )) || !left) 4565 { 4566 c.lineTo(0, h); 4567 } 4568 else 4569 { 4570 c.lineTo(size, h); 4571 } 4572 }; 4573 4574 mxShapeBasicRect2.prototype.paintSW = function(c, x, y, w, h, rectStyle, bottomLeftStyle, size, bottom) 4575 { 4576 if (!bottom) 4577 { 4578 c.lineTo(0, h); 4579 } 4580 else if((bottomLeftStyle == 'rounded' || (bottomLeftStyle == 'default' && rectStyle == 'rounded' )) || 4581 (bottomLeftStyle == 'invRound' || (bottomLeftStyle == 'default' && rectStyle == 'invRound' )) ) 4582 { 4583 var inv = 0; 4584 4585 if (bottomLeftStyle == 'rounded' || (bottomLeftStyle == 'default' && rectStyle == 'rounded' )) 4586 { 4587 inv = 1; 4588 } 4589 4590 c.arcTo(size, size, 0, 0, inv, 0, h - size); 4591 } 4592 else if((bottomLeftStyle == 'snip' || (bottomLeftStyle == 'default' && rectStyle == 'snip' )) || 4593 (bottomLeftStyle == 'fold' || (bottomLeftStyle == 'default' && rectStyle == 'fold' ))) 4594 { 4595 c.lineTo(0, h - size); 4596 } 4597 }; 4598 4599 mxShapeBasicRect2.prototype.paintNWInner = function(c, x, y, w, h, rectStyle, topLeftStyle, size, indent) 4600 { 4601 if(topLeftStyle == 'rounded' || (topLeftStyle == 'default' && rectStyle == 'rounded' )) 4602 { 4603 c.arcTo(size - indent * 0.5, size - indent * 0.5, 0, 0, 0, indent, indent * 0.5 + size); 4604 } 4605 else if(topLeftStyle == 'invRound' || (topLeftStyle == 'default' && rectStyle == 'invRound' )) 4606 { 4607 c.arcTo(size + indent, size + indent, 0, 0, 1, indent, indent + size); 4608 } 4609 else if(topLeftStyle == 'snip' || (topLeftStyle == 'default' && rectStyle == 'snip' )) 4610 { 4611 c.lineTo(indent, indent * 0.5 + size); 4612 } 4613 else if(topLeftStyle == 'fold' || (topLeftStyle == 'default' && rectStyle == 'fold' )) 4614 { 4615 c.lineTo(indent + size, indent + size); 4616 c.lineTo(indent, indent + size); 4617 } 4618 }; 4619 4620 mxShapeBasicRect2.prototype.paintTopInner = function(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, left, top) 4621 { 4622 if (!left && !top) 4623 { 4624 c.lineTo(0, 0); 4625 } 4626 else if (!left && top) 4627 { 4628 c.lineTo(0, indent); 4629 } 4630 else if (left && !top) 4631 { 4632 c.lineTo(indent, 0); 4633 } 4634 else if (!left) 4635 { 4636 c.lineTo(0, indent); 4637 } 4638 else if(topLeftStyle == 'square' || (topLeftStyle == 'default' && rectStyle == 'square' )) 4639 { 4640 c.lineTo(indent, indent); 4641 } 4642 else if((topLeftStyle == 'rounded' || (topLeftStyle == 'default' && rectStyle == 'rounded' )) || 4643 (topLeftStyle == 'snip' || (topLeftStyle == 'default' && rectStyle == 'snip' ))) 4644 { 4645 c.lineTo(size + indent * 0.5, indent); 4646 } 4647 else 4648 { 4649 c.lineTo(size + indent, indent); 4650 } 4651 }; 4652 4653 mxShapeBasicRect2.prototype.paintNEInner = function(c, x, y, w, h, rectStyle, topRightStyle, size, indent) 4654 { 4655 if(topRightStyle == 'rounded' || (topRightStyle == 'default' && rectStyle == 'rounded' )) 4656 { 4657 c.arcTo(size - indent * 0.5, size - indent * 0.5, 0, 0, 0, w - size - indent * 0.5, indent); 4658 } 4659 else if(topRightStyle == 'invRound' || (topRightStyle == 'default' && rectStyle == 'invRound' )) 4660 { 4661 c.arcTo(size + indent, size + indent, 0, 0, 1, w - size - indent, indent); 4662 } 4663 else if(topRightStyle == 'snip' || (topRightStyle == 'default' && rectStyle == 'snip' )) 4664 { 4665 c.lineTo(w - size - indent * 0.5, indent); 4666 } 4667 else if(topRightStyle == 'fold' || (topRightStyle == 'default' && rectStyle == 'fold' )) 4668 { 4669 c.lineTo(w - size - indent, size + indent); 4670 c.lineTo(w - size - indent, indent); 4671 } 4672 }; 4673 4674 mxShapeBasicRect2.prototype.paintRightInner = function(c, x, y, w, h, rectStyle, topRightStyle, size, indent, top, right) 4675 { 4676 if (!top && !right) 4677 { 4678 c.lineTo(w, 0); 4679 } 4680 else if (!top && right) 4681 { 4682 c.lineTo(w - indent, 0); 4683 } 4684 else if (top && !right) 4685 { 4686 c.lineTo(w, indent); 4687 } 4688 else if (!top) 4689 { 4690 c.lineTo(w - indent, 0); 4691 } 4692 else if(topRightStyle == 'square' || (topRightStyle == 'default' && rectStyle == 'square' )) 4693 { 4694 c.lineTo(w - indent, indent); 4695 } 4696 else if((topRightStyle == 'rounded' || (topRightStyle == 'default' && rectStyle == 'rounded' )) || 4697 (topRightStyle == 'snip' || (topRightStyle == 'default' && rectStyle == 'snip' ))) 4698 { 4699 c.lineTo(w - indent, size + indent * 0.5); 4700 } 4701 else 4702 { 4703 c.lineTo(w - indent, size + indent); 4704 } 4705 }; 4706 4707 mxShapeBasicRect2.prototype.paintLeftInner = function(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom, left) 4708 { 4709 if (!bottom && !left) 4710 { 4711 c.lineTo(0, h); 4712 } 4713 else if (!bottom && left) 4714 { 4715 c.lineTo(indent, h); 4716 } 4717 else if (bottom && !left) 4718 { 4719 c.lineTo(0, h - indent); 4720 } 4721 else if (!bottom) 4722 { 4723 c.lineTo(indent, h); 4724 } 4725 else if(bottomLeftStyle == 'square' || (bottomLeftStyle == 'default' && rectStyle == 'square' )) 4726 { 4727 c.lineTo(indent, h - indent); 4728 } 4729 else if((bottomLeftStyle == 'rounded' || (bottomLeftStyle == 'default' && rectStyle == 'rounded' )) || 4730 (bottomLeftStyle == 'snip' || (bottomLeftStyle == 'default' && rectStyle == 'snip' ))) 4731 { 4732 c.lineTo(indent, h - size - indent * 0.5); 4733 } 4734 else 4735 { 4736 c.lineTo(indent, h - size - indent); 4737 } 4738 }; 4739 4740 mxShapeBasicRect2.prototype.paintSEInner = function(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent) 4741 { 4742 if(bottomRightStyle == 'rounded' || (bottomRightStyle == 'default' && rectStyle == 'rounded' )) 4743 { 4744 c.arcTo(size - indent * 0.5, size - indent * 0.5, 0, 0, 0, w - indent, h - size - indent * 0.5); 4745 } 4746 else if(bottomRightStyle == 'invRound' || (bottomRightStyle == 'default' && rectStyle == 'invRound' )) 4747 { 4748 c.arcTo(size + indent, size + indent, 0, 0, 1, w - indent, h - size - indent); 4749 } 4750 else if(bottomRightStyle == 'snip' || (bottomRightStyle == 'default' && rectStyle == 'snip' )) 4751 { 4752 c.lineTo(w - indent, h - size - indent * 0.5); 4753 } 4754 else if(bottomRightStyle == 'fold' || (bottomRightStyle == 'default' && rectStyle == 'fold' )) 4755 { 4756 c.lineTo(w - size - indent, h - size - indent); 4757 c.lineTo(w - indent, h - size - indent); 4758 } 4759 }; 4760 4761 mxShapeBasicRect2.prototype.paintBottomInner = function(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, right, bottom) 4762 { 4763 if (!right && !bottom) 4764 { 4765 c.lineTo(w, h); 4766 } 4767 else if (!right && bottom) 4768 { 4769 c.lineTo(w, h - indent); 4770 } 4771 else if (right && !bottom) 4772 { 4773 c.lineTo(w - indent, h); 4774 } 4775 else if((bottomRightStyle == 'square' || (bottomRightStyle == 'default' && rectStyle == 'square' )) || !right) 4776 { 4777 c.lineTo(w - indent, h - indent); 4778 } 4779 else if((bottomRightStyle == 'rounded' || (bottomRightStyle == 'default' && rectStyle == 'rounded' )) || 4780 (bottomRightStyle == 'snip' || (bottomRightStyle == 'default' && rectStyle == 'snip' ))) 4781 { 4782 c.lineTo(w - size - indent * 0.5, h - indent); 4783 } 4784 else 4785 { 4786 c.lineTo(w - size - indent, h - indent); 4787 } 4788 }; 4789 4790 mxShapeBasicRect2.prototype.paintSWInner = function(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, bottom) 4791 { 4792 if (!bottom) 4793 { 4794 c.lineTo(indent, h); 4795 } 4796 else if(bottomLeftStyle == 'square' || (bottomLeftStyle == 'default' && rectStyle == 'square' )) 4797 { 4798 c.lineTo(indent, h - indent); 4799 } 4800 else if(bottomLeftStyle == 'rounded' || (bottomLeftStyle == 'default' && rectStyle == 'rounded' )) 4801 { 4802 c.arcTo(size - indent * 0.5, size - indent * 0.5, 0, 0, 0, size + indent * 0.5, h - indent); 4803 } 4804 else if(bottomLeftStyle == 'invRound' || (bottomLeftStyle == 'default' && rectStyle == 'invRound' )) 4805 { 4806 c.arcTo(size + indent, size + indent, 0, 0, 1, size + indent, h - indent); 4807 } 4808 else if(bottomLeftStyle == 'snip' || (bottomLeftStyle == 'default' && rectStyle == 'snip' )) 4809 { 4810 c.lineTo(size + indent * 0.5, h - indent); 4811 } 4812 else if(bottomLeftStyle == 'fold' || (bottomLeftStyle == 'default' && rectStyle == 'fold' )) 4813 { 4814 c.lineTo(indent + size, h - size - indent); 4815 c.lineTo(indent + size, h - indent); 4816 } 4817 }; 4818 4819 mxShapeBasicRect2.prototype.moveSWInner = function(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, left) 4820 { 4821 if (!left) 4822 { 4823 c.moveTo(0, h - indent); 4824 } 4825 else if(bottomLeftStyle == 'square' || (bottomLeftStyle == 'default' && rectStyle == 'square' )) 4826 { 4827 c.moveTo(indent, h - indent); 4828 } 4829 else if((bottomLeftStyle == 'rounded' || (bottomLeftStyle == 'default' && rectStyle == 'rounded' )) || 4830 (bottomLeftStyle == 'snip' || (bottomLeftStyle == 'default' && rectStyle == 'snip' ))) 4831 { 4832 c.moveTo(indent, h - size - indent * 0.5); 4833 } 4834 else if((bottomLeftStyle == 'invRound' || (bottomLeftStyle == 'default' && rectStyle == 'invRound' )) || 4835 (bottomLeftStyle == 'fold' || (bottomLeftStyle == 'default' && rectStyle == 'fold' ))) 4836 { 4837 c.moveTo(indent, h - size - indent); 4838 } 4839 }; 4840 4841 mxShapeBasicRect2.prototype.lineSWInner = function(c, x, y, w, h, rectStyle, bottomLeftStyle, size, indent, left) 4842 { 4843 if (!left) 4844 { 4845 c.lineTo(0, h - indent); 4846 } 4847 else if(bottomLeftStyle == 'square' || (bottomLeftStyle == 'default' && rectStyle == 'square' )) 4848 { 4849 c.lineTo(indent, h - indent); 4850 } 4851 else if((bottomLeftStyle == 'rounded' || (bottomLeftStyle == 'default' && rectStyle == 'rounded' )) || 4852 (bottomLeftStyle == 'snip' || (bottomLeftStyle == 'default' && rectStyle == 'snip' ))) 4853 { 4854 c.lineTo(indent, h - size - indent * 0.5); 4855 } 4856 else if((bottomLeftStyle == 'invRound' || (bottomLeftStyle == 'default' && rectStyle == 'invRound' )) || 4857 (bottomLeftStyle == 'fold' || (bottomLeftStyle == 'default' && rectStyle == 'fold' ))) 4858 { 4859 c.lineTo(indent, h - size - indent); 4860 } 4861 }; 4862 4863 mxShapeBasicRect2.prototype.moveSEInner = function(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, bottom) 4864 { 4865 if (!bottom) 4866 { 4867 c.moveTo(w - indent, h); 4868 } 4869 else if(bottomRightStyle == 'square' || (bottomRightStyle == 'default' && rectStyle == 'square' )) 4870 { 4871 c.moveTo(w - indent, h - indent); 4872 } 4873 else if((bottomRightStyle == 'rounded' || (bottomRightStyle == 'default' && rectStyle == 'rounded' )) || 4874 (bottomRightStyle == 'snip' || (bottomRightStyle == 'default' && rectStyle == 'snip' ))) 4875 { 4876 c.moveTo(w - indent, h - size - indent * 0.5); 4877 } 4878 else if((bottomRightStyle == 'invRound' || (bottomRightStyle == 'default' && rectStyle == 'invRound' )) || 4879 (bottomRightStyle == 'fold' || (bottomRightStyle == 'default' && rectStyle == 'fold' ))) 4880 { 4881 c.moveTo(w - indent, h - size - indent); 4882 } 4883 }; 4884 4885 mxShapeBasicRect2.prototype.lineSEInner = function(c, x, y, w, h, rectStyle, bottomRightStyle, size, indent, bottom) 4886 { 4887 if (!bottom) 4888 { 4889 c.lineTo(w - indent, h); 4890 } 4891 else if(bottomRightStyle == 'square' || (bottomRightStyle == 'default' && rectStyle == 'square' )) 4892 { 4893 c.lineTo(w - indent, h - indent); 4894 } 4895 else if((bottomRightStyle == 'rounded' || (bottomRightStyle == 'default' && rectStyle == 'rounded' )) || 4896 (bottomRightStyle == 'snip' || (bottomRightStyle == 'default' && rectStyle == 'snip' ))) 4897 { 4898 c.lineTo(w - indent, h - size - indent * 0.5); 4899 } 4900 else if((bottomRightStyle == 'invRound' || (bottomRightStyle == 'default' && rectStyle == 'invRound' )) || 4901 (bottomRightStyle == 'fold' || (bottomRightStyle == 'default' && rectStyle == 'fold' ))) 4902 { 4903 c.lineTo(w - indent, h - size - indent); 4904 } 4905 }; 4906 4907 mxShapeBasicRect2.prototype.moveNEInner = function(c, x, y, w, h, rectStyle, topRightStyle, size, indent, right) 4908 { 4909 if (!right) 4910 { 4911 c.moveTo(w, indent); 4912 } 4913 else if((topRightStyle == 'square' || (topRightStyle == 'default' && rectStyle == 'square' )) || right) 4914 { 4915 c.moveTo(w - indent, indent); 4916 } 4917 else if((topRightStyle == 'rounded' || (topRightStyle == 'default' && rectStyle == 'rounded' )) || 4918 (topRightStyle == 'snip' || (topRightStyle == 'default' && rectStyle == 'snip' ))) 4919 { 4920 c.moveTo(w - indent, size + indent * 0.5); 4921 } 4922 else if((topRightStyle == 'invRound' || (topRightStyle == 'default' && rectStyle == 'invRound' )) || 4923 (topRightStyle == 'fold' || (topRightStyle == 'default' && rectStyle == 'fold' ))) 4924 { 4925 c.moveTo(w - indent, size + indent); 4926 } 4927 }; 4928 4929 mxShapeBasicRect2.prototype.lineNEInner = function(c, x, y, w, h, rectStyle, topRightStyle, size, indent, right) 4930 { 4931 if (!right) 4932 { 4933 c.lineTo(w, indent); 4934 } 4935 else if((topRightStyle == 'square' || (topRightStyle == 'default' && rectStyle == 'square' )) || right) 4936 { 4937 c.lineTo(w - indent, indent); 4938 } 4939 else if((topRightStyle == 'rounded' || (topRightStyle == 'default' && rectStyle == 'rounded' )) || 4940 (topRightStyle == 'snip' || (topRightStyle == 'default' && rectStyle == 'snip' ))) 4941 { 4942 c.lineTo(w - indent, size + indent * 0.5); 4943 } 4944 else if((topRightStyle == 'invRound' || (topRightStyle == 'default' && rectStyle == 'invRound' )) || 4945 (topRightStyle == 'fold' || (topRightStyle == 'default' && rectStyle == 'fold' ))) 4946 { 4947 c.lineTo(w - indent, size + indent); 4948 } 4949 }; 4950 4951 mxShapeBasicRect2.prototype.moveNWInner = function(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, top, left) 4952 { 4953 if (!top && !left) 4954 { 4955 c.moveTo(0, 0); 4956 } 4957 else if (!top && left) 4958 { 4959 c.moveTo(indent, 0); 4960 } 4961 else if (top && !left) 4962 { 4963 c.moveTo(0, indent); 4964 } 4965 else if(topLeftStyle == 'square' || (topLeftStyle == 'default' && rectStyle == 'square' )) 4966 { 4967 c.moveTo(indent, indent); 4968 } 4969 else if((topLeftStyle == 'rounded' || (topLeftStyle == 'default' && rectStyle == 'rounded' )) || 4970 (topLeftStyle == 'snip' || (topLeftStyle == 'default' && rectStyle == 'snip' ))) 4971 { 4972 c.moveTo(indent, size + indent * 0.5); 4973 } 4974 else if((topLeftStyle == 'invRound' || (topLeftStyle == 'default' && rectStyle == 'invRound' )) || 4975 (topLeftStyle == 'fold' || (topLeftStyle == 'default' && rectStyle == 'fold' ))) 4976 { 4977 c.moveTo(indent, size + indent); 4978 } 4979 }; 4980 4981 mxShapeBasicRect2.prototype.lineNWInner = function(c, x, y, w, h, rectStyle, topLeftStyle, size, indent, top, left) 4982 { 4983 if (!top && !left) 4984 { 4985 c.lineTo(0, 0); 4986 } 4987 else if (!top && left) 4988 { 4989 c.lineTo(indent, 0); 4990 } 4991 else if (top && !left) 4992 { 4993 c.lineTo(0, indent); 4994 } 4995 else if(topLeftStyle == 'square' || (topLeftStyle == 'default' && rectStyle == 'square' )) 4996 { 4997 c.lineTo(indent, indent); 4998 } 4999 else if((topLeftStyle == 'rounded' || (topLeftStyle == 'default' && rectStyle == 'rounded' )) || 5000 (topLeftStyle == 'snip' || (topLeftStyle == 'default' && rectStyle == 'snip' ))) 5001 { 5002 c.lineTo(indent, size + indent * 0.5); 5003 } 5004 else if((topLeftStyle == 'invRound' || (topLeftStyle == 'default' && rectStyle == 'invRound' )) || 5005 (topLeftStyle == 'fold' || (topLeftStyle == 'default' && rectStyle == 'fold' ))) 5006 { 5007 c.lineTo(indent, size + indent); 5008 } 5009 }; 5010 5011 mxShapeBasicRect2.prototype.paintFolds = function(c, x, y, w, h, rectStyle, topLeftStyle, topRightStyle, bottomRightStyle, bottomLeftStyle, size, top, right, bottom, left) 5012 { 5013 if (rectStyle == 'fold' || topLeftStyle == 'fold' || topRightStyle == 'fold' || bottomRightStyle == 'fold' || bottomLeftStyle == 'fold') 5014 { 5015 if ((topLeftStyle == 'fold' || (topLeftStyle == 'default' && rectStyle == 'fold' )) && (top && left)) 5016 { 5017 c.moveTo(0, size); 5018 c.lineTo(size, size); 5019 c.lineTo(size, 0); 5020 } 5021 5022 if ((topRightStyle == 'fold' || (topRightStyle == 'default' && rectStyle == 'fold' )) && (top && right)) 5023 { 5024 c.moveTo(w - size, 0); 5025 c.lineTo(w - size, size); 5026 c.lineTo(w, size); 5027 } 5028 5029 if ((bottomRightStyle == 'fold' || (bottomRightStyle == 'default' && rectStyle == 'fold' )) && (bottom && right)) 5030 { 5031 c.moveTo(w - size, h); 5032 c.lineTo(w - size, h - size); 5033 c.lineTo(w, h - size); 5034 } 5035 5036 if ((bottomLeftStyle == 'fold' || (bottomLeftStyle == 'default' && rectStyle == 'fold' )) && (bottom && left)) 5037 { 5038 c.moveTo(0, h - size); 5039 c.lineTo(size, h - size); 5040 c.lineTo(size, h); 5041 } 5042 } 5043 }; 5044 5045 mxCellRenderer.registerShape(mxShapeBasicRect2.prototype.cst.RECT2, mxShapeBasicRect2); 5046 5047 mxShapeBasicRect2.prototype.constraints = null; 5048 5049 // FilledEdge shape 5050 function FilledEdge() 5051 { 5052 mxConnector.call(this); 5053 }; 5054 mxUtils.extend(FilledEdge, mxConnector); 5055 5056 FilledEdge.prototype.origPaintEdgeShape = FilledEdge.prototype.paintEdgeShape; 5057 FilledEdge.prototype.paintEdgeShape = function(c, pts, rounded) 5058 { 5059 // Markers modify incoming points array 5060 var temp = []; 5061 5062 for (var i = 0; i < pts.length; i++) 5063 { 5064 temp.push(mxUtils.clone(pts[i])); 5065 } 5066 5067 // paintEdgeShape resets dashed to false 5068 var dashed = c.state.dashed; 5069 var fixDash = c.state.fixDash; 5070 FilledEdge.prototype.origPaintEdgeShape.apply(this, [c, temp, rounded]); 5071 5072 if (c.state.strokeWidth >= 3) 5073 { 5074 var fillClr = mxUtils.getValue(this.style, 'fillColor', null); 5075 5076 if (fillClr != null) 5077 { 5078 c.setStrokeColor(fillClr); 5079 c.setStrokeWidth(c.state.strokeWidth - 2); 5080 c.setDashed(dashed, fixDash); 5081 5082 FilledEdge.prototype.origPaintEdgeShape.apply(this, [c, pts, rounded]); 5083 } 5084 } 5085 }; 5086 5087 // Registers the link shape 5088 mxCellRenderer.registerShape('filledEdge', FilledEdge); 5089 5090 // Implements custom colors for shapes 5091 if (typeof StyleFormatPanel !== 'undefined') 5092 { 5093 (function() 5094 { 5095 var styleFormatPanelGetCustomColors = StyleFormatPanel.prototype.getCustomColors; 5096 5097 StyleFormatPanel.prototype.getCustomColors = function() 5098 { 5099 var ss = this.format.getSelectionState(); 5100 var result = styleFormatPanelGetCustomColors.apply(this, arguments); 5101 5102 if (ss.style.shape == 'umlFrame') 5103 { 5104 result.push({title: mxResources.get('laneColor'), key: 'swimlaneFillColor', defaultValue: '#ffffff'}); 5105 } 5106 5107 return result; 5108 }; 5109 })(); 5110 } 5111 5112 // Registers and defines the custom marker 5113 mxMarker.addMarker('dash', function(c, shape, type, pe, unitX, unitY, size, source, sw, filled) 5114 { 5115 var nx = unitX * (size + sw + 1); 5116 var ny = unitY * (size + sw + 1); 5117 5118 return function() 5119 { 5120 c.begin(); 5121 c.moveTo(pe.x - nx / 2 - ny / 2, pe.y - ny / 2 + nx / 2); 5122 c.lineTo(pe.x + ny / 2 - 3 * nx / 2, pe.y - 3 * ny / 2 - nx / 2); 5123 c.stroke(); 5124 }; 5125 }); 5126 5127 // Registers and defines the custom marker 5128 mxMarker.addMarker('box', function(c, shape, type, pe, unitX, unitY, size, source, sw, filled) 5129 { 5130 var nx = unitX * (size + sw + 1); 5131 var ny = unitY * (size + sw + 1); 5132 var px = pe.x + nx / 2; 5133 var py = pe.y + ny / 2; 5134 5135 pe.x -= nx; 5136 pe.y -= ny; 5137 5138 return function() 5139 { 5140 c.begin(); 5141 c.moveTo(px - nx / 2 - ny / 2, py - ny / 2 + nx / 2); 5142 c.lineTo(px - nx / 2 + ny / 2, py - ny / 2 - nx / 2); 5143 c.lineTo(px + ny / 2 - 3 * nx / 2, py - 3 * ny / 2 - nx / 2); 5144 c.lineTo(px - ny / 2 - 3 * nx / 2, py - 3 * ny / 2 + nx / 2); 5145 c.close(); 5146 5147 if (filled) 5148 { 5149 c.fillAndStroke(); 5150 } 5151 else 5152 { 5153 c.stroke(); 5154 } 5155 }; 5156 }); 5157 5158 // Registers and defines the custom marker 5159 mxMarker.addMarker('cross', function(c, shape, type, pe, unitX, unitY, size, source, sw, filled) 5160 { 5161 var nx = unitX * (size + sw + 1); 5162 var ny = unitY * (size + sw + 1); 5163 5164 return function() 5165 { 5166 c.begin(); 5167 c.moveTo(pe.x - nx / 2 - ny / 2, pe.y - ny / 2 + nx / 2); 5168 c.lineTo(pe.x + ny / 2 - 3 * nx / 2, pe.y - 3 * ny / 2 - nx / 2); 5169 c.moveTo(pe.x - nx / 2 + ny / 2, pe.y - ny / 2 - nx / 2); 5170 c.lineTo(pe.x - ny / 2 - 3 * nx / 2, pe.y - 3 * ny / 2 + nx / 2); 5171 c.stroke(); 5172 }; 5173 }); 5174 5175 function circleMarker(c, shape, type, pe, unitX, unitY, size, source, sw, filled) 5176 { 5177 var a = size / 2; 5178 var size = size + sw; 5179 5180 var pt = pe.clone(); 5181 5182 pe.x -= unitX * (2 * size + sw); 5183 pe.y -= unitY * (2 * size + sw); 5184 5185 unitX = unitX * (size + sw); 5186 unitY = unitY * (size + sw); 5187 5188 return function() 5189 { 5190 c.ellipse(pt.x - unitX - size, pt.y - unitY - size, 2 * size, 2 * size); 5191 5192 if (filled) 5193 { 5194 c.fillAndStroke(); 5195 } 5196 else 5197 { 5198 c.stroke(); 5199 } 5200 }; 5201 }; 5202 5203 mxMarker.addMarker('circle', circleMarker); 5204 mxMarker.addMarker('circlePlus', function(c, shape, type, pe, unitX, unitY, size, source, sw, filled) 5205 { 5206 var pt = pe.clone(); 5207 var fn = circleMarker.apply(this, arguments); 5208 var nx = unitX * (size + 2 * sw); // (size + sw + 1); 5209 var ny = unitY * (size + 2 * sw); //(size + sw + 1); 5210 5211 return function() 5212 { 5213 fn.apply(this, arguments); 5214 5215 c.begin(); 5216 c.moveTo(pt.x - unitX * (sw), pt.y - unitY * (sw)); 5217 c.lineTo(pt.x - 2 * nx + unitX * (sw), pt.y - 2 * ny + unitY * (sw)); 5218 c.moveTo(pt.x - nx - ny + unitY * sw, pt.y - ny + nx - unitX * sw); 5219 c.lineTo(pt.x + ny - nx - unitY * sw, pt.y - ny - nx + unitX * sw); 5220 c.stroke(); 5221 }; 5222 }); 5223 5224 // Registers and defines the custom marker 5225 mxMarker.addMarker('halfCircle', function(c, shape, type, pe, unitX, unitY, size, source, sw, filled) 5226 { 5227 var nx = unitX * (size + sw + 1); 5228 var ny = unitY * (size + sw + 1); 5229 var pt = pe.clone(); 5230 5231 pe.x -= nx; 5232 pe.y -= ny; 5233 5234 return function() 5235 { 5236 c.begin(); 5237 c.moveTo(pt.x - ny, pt.y + nx); 5238 c.quadTo(pe.x - ny, pe.y + nx, pe.x, pe.y); 5239 c.quadTo(pe.x + ny, pe.y - nx, pt.x + ny, pt.y - nx); 5240 c.stroke(); 5241 }; 5242 }); 5243 5244 mxMarker.addMarker('async', function(c, shape, type, pe, unitX, unitY, size, source, sw, filled) 5245 { 5246 // The angle of the forward facing arrow sides against the x axis is 5247 // 26.565 degrees, 1/sin(26.565) = 2.236 / 2 = 1.118 ( / 2 allows for 5248 // only half the strokewidth is processed ). 5249 var endOffsetX = unitX * sw * 1.118; 5250 var endOffsetY = unitY * sw * 1.118; 5251 5252 unitX = unitX * (size + sw); 5253 unitY = unitY * (size + sw); 5254 5255 var pt = pe.clone(); 5256 pt.x -= endOffsetX; 5257 pt.y -= endOffsetY; 5258 5259 var f = 1; 5260 pe.x += -unitX * f - endOffsetX; 5261 pe.y += -unitY * f - endOffsetY; 5262 5263 return function() 5264 { 5265 c.begin(); 5266 c.moveTo(pt.x, pt.y); 5267 5268 if (source) 5269 { 5270 c.lineTo(pt.x - unitX - unitY / 2, pt.y - unitY + unitX / 2); 5271 } 5272 else 5273 { 5274 c.lineTo(pt.x + unitY / 2 - unitX, pt.y - unitY - unitX / 2); 5275 } 5276 5277 c.lineTo(pt.x - unitX, pt.y - unitY); 5278 c.close(); 5279 5280 if (filled) 5281 { 5282 c.fillAndStroke(); 5283 } 5284 else 5285 { 5286 c.stroke(); 5287 } 5288 }; 5289 }); 5290 5291 function createOpenAsyncArrow(widthFactor) 5292 { 5293 widthFactor = (widthFactor != null) ? widthFactor : 2; 5294 5295 return function(c, shape, type, pe, unitX, unitY, size, source, sw, filled) 5296 { 5297 unitX = unitX * (size + sw); 5298 unitY = unitY * (size + sw); 5299 5300 var pt = pe.clone(); 5301 5302 return function() 5303 { 5304 c.begin(); 5305 c.moveTo(pt.x, pt.y); 5306 5307 if (source) 5308 { 5309 c.lineTo(pt.x - unitX - unitY / widthFactor, pt.y - unitY + unitX / widthFactor); 5310 } 5311 else 5312 { 5313 c.lineTo(pt.x + unitY / widthFactor - unitX, pt.y - unitY - unitX / widthFactor); 5314 } 5315 5316 c.stroke(); 5317 }; 5318 } 5319 }; 5320 5321 mxMarker.addMarker('openAsync', createOpenAsyncArrow(2)); 5322 5323 function arrow(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled) 5324 { 5325 // The angle of the forward facing arrow sides against the x axis is 5326 // 26.565 degrees, 1/sin(26.565) = 2.236 / 2 = 1.118 ( / 2 allows for 5327 // only half the strokewidth is processed ). 5328 var endOffsetX = unitX * sw * 1.118; 5329 var endOffsetY = unitY * sw * 1.118; 5330 5331 unitX = unitX * (size + sw); 5332 unitY = unitY * (size + sw); 5333 5334 var pt = pe.clone(); 5335 pt.x -= endOffsetX; 5336 pt.y -= endOffsetY; 5337 5338 var f = (type != mxConstants.ARROW_CLASSIC && type != mxConstants.ARROW_CLASSIC_THIN) ? 1 : 3 / 4; 5339 pe.x += -unitX * f - endOffsetX; 5340 pe.y += -unitY * f - endOffsetY; 5341 5342 return function() 5343 { 5344 canvas.begin(); 5345 canvas.moveTo(pt.x, pt.y); 5346 canvas.lineTo(pt.x - unitX - unitY / widthFactor, pt.y - unitY + unitX / widthFactor); 5347 5348 if (type == mxConstants.ARROW_CLASSIC || type == mxConstants.ARROW_CLASSIC_THIN) 5349 { 5350 canvas.lineTo(pt.x - unitX * 3 / 4, pt.y - unitY * 3 / 4); 5351 } 5352 5353 canvas.lineTo(pt.x + unitY / widthFactor - unitX, pt.y - unitY - unitX / widthFactor); 5354 canvas.close(); 5355 5356 if (filled) 5357 { 5358 canvas.fillAndStroke(); 5359 } 5360 else 5361 { 5362 canvas.stroke(); 5363 } 5364 }; 5365 } 5366 5367 // Handlers are only added if mxVertexHandler is defined (ie. not in embedded graph) 5368 if (typeof mxVertexHandler !== 'undefined') 5369 { 5370 function createHandle(state, keys, getPositionFn, setPositionFn, ignoreGrid, redrawEdges, executeFn) 5371 { 5372 var handle = new mxHandle(state, null, mxVertexHandler.prototype.secondaryHandleImage); 5373 5374 handle.execute = function(me) 5375 { 5376 for (var i = 0; i < keys.length; i++) 5377 { 5378 this.copyStyle(keys[i]); 5379 } 5380 5381 if (executeFn) 5382 { 5383 executeFn(me); 5384 } 5385 }; 5386 5387 handle.getPosition = getPositionFn; 5388 handle.setPosition = setPositionFn; 5389 handle.ignoreGrid = (ignoreGrid != null) ? ignoreGrid : true; 5390 5391 // Overridden to update connected edges 5392 if (redrawEdges) 5393 { 5394 var positionChanged = handle.positionChanged; 5395 5396 handle.positionChanged = function() 5397 { 5398 positionChanged.apply(this, arguments); 5399 5400 // Redraws connected edges TODO: Include child edges 5401 state.view.invalidate(this.state.cell); 5402 state.view.validate(); 5403 }; 5404 } 5405 5406 return handle; 5407 }; 5408 5409 function createArcHandle(state, yOffset) 5410 { 5411 return createHandle(state, [mxConstants.STYLE_ARCSIZE], function(bounds) 5412 { 5413 var tmp = (yOffset != null) ? yOffset : bounds.height / 8; 5414 5415 if (mxUtils.getValue(state.style, mxConstants.STYLE_ABSOLUTE_ARCSIZE, 0) == '1') 5416 { 5417 var arcSize = mxUtils.getValue(state.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2; 5418 5419 return new mxPoint(bounds.x + bounds.width - Math.min(bounds.width / 2, arcSize), bounds.y + tmp); 5420 } 5421 else 5422 { 5423 var arcSize = Math.max(0, parseFloat(mxUtils.getValue(state.style, 5424 mxConstants.STYLE_ARCSIZE, mxConstants.RECTANGLE_ROUNDING_FACTOR * 100))) / 100; 5425 5426 return new mxPoint(bounds.x + bounds.width - Math.min(Math.max(bounds.width / 2, bounds.height / 2), 5427 Math.min(bounds.width, bounds.height) * arcSize), bounds.y + tmp); 5428 } 5429 }, function(bounds, pt, me) 5430 { 5431 if (mxUtils.getValue(state.style, mxConstants.STYLE_ABSOLUTE_ARCSIZE, 0) == '1') 5432 { 5433 this.state.style[mxConstants.STYLE_ARCSIZE] = Math.round(Math.max(0, Math.min(bounds.width, 5434 (bounds.x + bounds.width - pt.x) * 2))); 5435 } 5436 else 5437 { 5438 var f = Math.min(50, Math.max(0, (bounds.width - pt.x + bounds.x) * 100 / 5439 Math.min(bounds.width, bounds.height))); 5440 this.state.style[mxConstants.STYLE_ARCSIZE] = Math.round(f); 5441 } 5442 }); 5443 } 5444 5445 function createArcHandleFunction() 5446 { 5447 return function(state) 5448 { 5449 var handles = []; 5450 5451 if (mxUtils.getValue(state.style, mxConstants.STYLE_ROUNDED, false)) 5452 { 5453 handles.push(createArcHandle(state)); 5454 } 5455 5456 return handles; 5457 }; 5458 }; 5459 5460 function createTrapezoidHandleFunction(max, defaultValue, fixedDefaultValue) 5461 { 5462 max = (max != null) ? max : 0.5; 5463 5464 return function(state) 5465 { 5466 var handles = [createHandle(state, ['size'], function(bounds) 5467 { 5468 var fixed = (fixedDefaultValue != null) ? mxUtils.getValue(this.state.style, 'fixedSize', '0') != '0' : null; 5469 var size = Math.max(0, parseFloat(mxUtils.getValue(this.state.style, 'size', (fixed) ? fixedDefaultValue : defaultValue))); 5470 5471 return new mxPoint(bounds.x + Math.min(bounds.width * 0.75 * max, size * ((fixed) ? 0.75 : bounds.width * 0.75)), bounds.y + bounds.height / 4); 5472 }, function(bounds, pt) 5473 { 5474 var fixed = (fixedDefaultValue != null) ? mxUtils.getValue(this.state.style, 'fixedSize', '0') != '0' : null; 5475 var size = (fixed) ? (pt.x - bounds.x) : Math.max(0, Math.min(max, (pt.x - bounds.x) / bounds.width * 0.75)); 5476 5477 this.state.style['size'] = size; 5478 }, false, true)]; 5479 5480 if (mxUtils.getValue(state.style, mxConstants.STYLE_ROUNDED, false)) 5481 { 5482 handles.push(createArcHandle(state)); 5483 } 5484 5485 return handles; 5486 }; 5487 }; 5488 5489 function createDisplayHandleFunction(defaultValue, allowArcHandle, max, redrawEdges, fixedDefaultValue) 5490 { 5491 max = (max != null) ? max : 0.5; 5492 5493 return function(state) 5494 { 5495 var handles = [createHandle(state, ['size'], function(bounds) 5496 { 5497 var fixed = (fixedDefaultValue != null) ? mxUtils.getValue(this.state.style, 'fixedSize', '0') != '0' : null; 5498 var size = parseFloat(mxUtils.getValue(this.state.style, 'size', (fixed) ? fixedDefaultValue : defaultValue)); 5499 5500 return new mxPoint(bounds.x + Math.max(0, Math.min(bounds.width * 0.5, size * ((fixed) ? 1 : bounds.width))), bounds.getCenterY()); 5501 }, function(bounds, pt, me) 5502 { 5503 var fixed = (fixedDefaultValue != null) ? mxUtils.getValue(this.state.style, 'fixedSize', '0') != '0' : null; 5504 var size = (fixed) ? (pt.x - bounds.x) : Math.max(0, Math.min(max, (pt.x - bounds.x) / bounds.width)); 5505 5506 this.state.style['size'] = size; 5507 }, false, redrawEdges)]; 5508 5509 if (allowArcHandle && mxUtils.getValue(state.style, mxConstants.STYLE_ROUNDED, false)) 5510 { 5511 handles.push(createArcHandle(state)); 5512 } 5513 5514 return handles; 5515 }; 5516 }; 5517 5518 function createCubeHandleFunction(factor, defaultValue, allowArcHandle) 5519 { 5520 return function(state) 5521 { 5522 var handles = [createHandle(state, ['size'], function(bounds) 5523 { 5524 var size = Math.max(0, Math.min(bounds.width, Math.min(bounds.height, parseFloat( 5525 mxUtils.getValue(this.state.style, 'size', defaultValue))))) * factor; 5526 5527 return new mxPoint(bounds.x + size, bounds.y + size); 5528 }, function(bounds, pt) 5529 { 5530 this.state.style['size'] = Math.round(Math.max(0, Math.min(Math.min(bounds.width, pt.x - bounds.x), 5531 Math.min(bounds.height, pt.y - bounds.y))) / factor); 5532 }, false)]; 5533 5534 if (allowArcHandle && mxUtils.getValue(state.style, mxConstants.STYLE_ROUNDED, false)) 5535 { 5536 handles.push(createArcHandle(state)); 5537 } 5538 5539 return handles; 5540 }; 5541 }; 5542 5543 function createCylinderHandleFunction(defaultValue) 5544 { 5545 return function(state) 5546 { 5547 return [createHandle(state, ['size'], function(bounds) 5548 { 5549 var size = Math.max(0, Math.min(bounds.height * 0.5, parseFloat(mxUtils.getValue(this.state.style, 'size', defaultValue)))); 5550 5551 return new mxPoint(bounds.x, bounds.y + size); 5552 }, function(bounds, pt) 5553 { 5554 this.state.style['size'] = Math.max(0, pt.y - bounds.y); 5555 }, true)]; 5556 } 5557 }; 5558 5559 function createArrowHandleFunction(maxSize) 5560 { 5561 return function(state) 5562 { 5563 return [createHandle(state, ['arrowWidth', 'arrowSize'], function(bounds) 5564 { 5565 var aw = Math.max(0, Math.min(1, mxUtils.getValue(this.state.style, 'arrowWidth', SingleArrowShape.prototype.arrowWidth))); 5566 var as = Math.max(0, Math.min(maxSize, mxUtils.getValue(this.state.style, 'arrowSize', SingleArrowShape.prototype.arrowSize))); 5567 5568 return new mxPoint(bounds.x + (1 - as) * bounds.width, bounds.y + (1 - aw) * bounds.height / 2); 5569 }, function(bounds, pt) 5570 { 5571 this.state.style['arrowWidth'] = Math.max(0, Math.min(1, Math.abs(bounds.y + bounds.height / 2 - pt.y) / bounds.height * 2)); 5572 this.state.style['arrowSize'] = Math.max(0, Math.min(maxSize, (bounds.x + bounds.width - pt.x) / (bounds.width))); 5573 })]; 5574 }; 5575 }; 5576 5577 function createEdgeHandle(state, keys, start, getPosition, setPosition) 5578 { 5579 return createHandle(state, keys, function(bounds) 5580 { 5581 var pts = state.absolutePoints; 5582 var n = pts.length - 1; 5583 5584 var tr = state.view.translate; 5585 var s = state.view.scale; 5586 5587 var p0 = (start) ? pts[0] : pts[n]; 5588 var p1 = (start) ? pts[1] : pts[n - 1]; 5589 var dx = (start) ? p1.x - p0.x : p1.x - p0.x; 5590 var dy = (start) ? p1.y - p0.y : p1.y - p0.y; 5591 5592 var dist = Math.sqrt(dx * dx + dy * dy); 5593 5594 var pt = getPosition.call(this, dist, dx / dist, dy / dist, p0, p1); 5595 5596 return new mxPoint(pt.x / s - tr.x, pt.y / s - tr.y); 5597 }, function(bounds, pt, me) 5598 { 5599 var pts = state.absolutePoints; 5600 var n = pts.length - 1; 5601 5602 var tr = state.view.translate; 5603 var s = state.view.scale; 5604 5605 var p0 = (start) ? pts[0] : pts[n]; 5606 var p1 = (start) ? pts[1] : pts[n - 1]; 5607 var dx = (start) ? p1.x - p0.x : p1.x - p0.x; 5608 var dy = (start) ? p1.y - p0.y : p1.y - p0.y; 5609 5610 var dist = Math.sqrt(dx * dx + dy * dy); 5611 pt.x = (pt.x + tr.x) * s; 5612 pt.y = (pt.y + tr.y) * s; 5613 5614 setPosition.call(this, dist, dx / dist, dy / dist, p0, p1, pt, me); 5615 }); 5616 }; 5617 5618 function createEdgeWidthHandle(state, start, spacing) 5619 { 5620 return createEdgeHandle(state, ['width'], start, function(dist, nx, ny, p0, p1) 5621 { 5622 var w = state.shape.getEdgeWidth() * state.view.scale + spacing; 5623 5624 return new mxPoint(p0.x + nx * dist / 4 + ny * w / 2, p0.y + ny * dist / 4 - nx * w / 2); 5625 }, function(dist, nx, ny, p0, p1, pt) 5626 { 5627 var w = Math.sqrt(mxUtils.ptSegDistSq(p0.x, p0.y, p1.x, p1.y, pt.x, pt.y)); 5628 state.style['width'] = Math.round(w * 2) / state.view.scale - spacing; 5629 }); 5630 }; 5631 5632 function ptLineDistance(x1, y1, x2, y2, x0, y0) 5633 { 5634 return Math.abs((y2 - y1) * x0 - (x2 - x1) * y0 + x2 * y1 - y2 * x1) / Math.sqrt((y2 - y1) * (y2 - y1) + (x2 - x1) * (x2 - x1)); 5635 } 5636 5637 var handleFactory = { 5638 'link': function(state) 5639 { 5640 var spacing = 10; 5641 5642 return [createEdgeWidthHandle(state, true, spacing), createEdgeWidthHandle(state, false, spacing)]; 5643 }, 5644 'flexArrow': function(state) 5645 { 5646 // Do not use state.shape.startSize/endSize since it is cached 5647 var tol = state.view.graph.gridSize / state.view.scale; 5648 var handles = []; 5649 5650 if (mxUtils.getValue(state.style, mxConstants.STYLE_STARTARROW, mxConstants.NONE) != mxConstants.NONE) 5651 { 5652 handles.push(createEdgeHandle(state, ['width', mxConstants.STYLE_STARTSIZE, mxConstants.STYLE_ENDSIZE], true, function(dist, nx, ny, p0, p1) 5653 { 5654 var w = (state.shape.getEdgeWidth() - state.shape.strokewidth) * state.view.scale; 5655 var l = mxUtils.getNumber(state.style, mxConstants.STYLE_STARTSIZE, mxConstants.ARROW_SIZE / 5) * 3 * state.view.scale; 5656 5657 return new mxPoint(p0.x + nx * (l + state.shape.strokewidth * state.view.scale) + ny * w / 2, 5658 p0.y + ny * (l + state.shape.strokewidth * state.view.scale) - nx * w / 2); 5659 }, function(dist, nx, ny, p0, p1, pt, me) 5660 { 5661 var w = Math.sqrt(mxUtils.ptSegDistSq(p0.x, p0.y, p1.x, p1.y, pt.x, pt.y)); 5662 var l = mxUtils.ptLineDist(p0.x, p0.y, p0.x + ny, p0.y - nx, pt.x, pt.y); 5663 5664 state.style[mxConstants.STYLE_STARTSIZE] = Math.round((l - state.shape.strokewidth) * 100 / 3) / 100 / state.view.scale; 5665 state.style['width'] = Math.round(w * 2) / state.view.scale; 5666 5667 // Applies to opposite side 5668 if (mxEvent.isControlDown(me.getEvent())) 5669 { 5670 state.style[mxConstants.STYLE_ENDSIZE] = state.style[mxConstants.STYLE_STARTSIZE]; 5671 } 5672 5673 // Snaps to end geometry 5674 if (!mxEvent.isAltDown(me.getEvent())) 5675 { 5676 if (Math.abs(parseFloat(state.style[mxConstants.STYLE_STARTSIZE]) - parseFloat(state.style[mxConstants.STYLE_ENDSIZE])) < tol / 6) 5677 { 5678 state.style[mxConstants.STYLE_STARTSIZE] = state.style[mxConstants.STYLE_ENDSIZE]; 5679 } 5680 } 5681 })); 5682 5683 handles.push(createEdgeHandle(state, ['startWidth', 'endWidth', mxConstants.STYLE_STARTSIZE, mxConstants.STYLE_ENDSIZE], true, function(dist, nx, ny, p0, p1) 5684 { 5685 var w = (state.shape.getStartArrowWidth() - state.shape.strokewidth) * state.view.scale; 5686 var l = mxUtils.getNumber(state.style, mxConstants.STYLE_STARTSIZE, mxConstants.ARROW_SIZE / 5) * 3 * state.view.scale; 5687 5688 return new mxPoint(p0.x + nx * (l + state.shape.strokewidth * state.view.scale) + ny * w / 2, 5689 p0.y + ny * (l + state.shape.strokewidth * state.view.scale) - nx * w / 2); 5690 }, function(dist, nx, ny, p0, p1, pt, me) 5691 { 5692 var w = Math.sqrt(mxUtils.ptSegDistSq(p0.x, p0.y, p1.x, p1.y, pt.x, pt.y)); 5693 var l = mxUtils.ptLineDist(p0.x, p0.y, p0.x + ny, p0.y - nx, pt.x, pt.y); 5694 5695 state.style[mxConstants.STYLE_STARTSIZE] = Math.round((l - state.shape.strokewidth) * 100 / 3) / 100 / state.view.scale; 5696 state.style['startWidth'] = Math.max(0, Math.round(w * 2) - state.shape.getEdgeWidth()) / state.view.scale; 5697 5698 // Applies to opposite side 5699 if (mxEvent.isControlDown(me.getEvent())) 5700 { 5701 state.style[mxConstants.STYLE_ENDSIZE] = state.style[mxConstants.STYLE_STARTSIZE]; 5702 state.style['endWidth'] = state.style['startWidth']; 5703 } 5704 5705 // Snaps to endWidth 5706 if (!mxEvent.isAltDown(me.getEvent())) 5707 { 5708 if (Math.abs(parseFloat(state.style[mxConstants.STYLE_STARTSIZE]) - parseFloat(state.style[mxConstants.STYLE_ENDSIZE])) < tol / 6) 5709 { 5710 state.style[mxConstants.STYLE_STARTSIZE] = state.style[mxConstants.STYLE_ENDSIZE]; 5711 } 5712 5713 if (Math.abs(parseFloat(state.style['startWidth']) - parseFloat(state.style['endWidth'])) < tol) 5714 { 5715 state.style['startWidth'] = state.style['endWidth']; 5716 } 5717 } 5718 })); 5719 } 5720 5721 if (mxUtils.getValue(state.style, mxConstants.STYLE_ENDARROW, mxConstants.NONE) != mxConstants.NONE) 5722 { 5723 handles.push(createEdgeHandle(state, ['width', mxConstants.STYLE_STARTSIZE, mxConstants.STYLE_ENDSIZE], false, function(dist, nx, ny, p0, p1) 5724 { 5725 var w = (state.shape.getEdgeWidth() - state.shape.strokewidth) * state.view.scale; 5726 var l = mxUtils.getNumber(state.style, mxConstants.STYLE_ENDSIZE, mxConstants.ARROW_SIZE / 5) * 3 * state.view.scale; 5727 5728 return new mxPoint(p0.x + nx * (l + state.shape.strokewidth * state.view.scale) - ny * w / 2, 5729 p0.y + ny * (l + state.shape.strokewidth * state.view.scale) + nx * w / 2); 5730 }, function(dist, nx, ny, p0, p1, pt, me) 5731 { 5732 var w = Math.sqrt(mxUtils.ptSegDistSq(p0.x, p0.y, p1.x, p1.y, pt.x, pt.y)); 5733 var l = mxUtils.ptLineDist(p0.x, p0.y, p0.x + ny, p0.y - nx, pt.x, pt.y); 5734 5735 state.style[mxConstants.STYLE_ENDSIZE] = Math.round((l - state.shape.strokewidth) * 100 / 3) / 100 / state.view.scale; 5736 state.style['width'] = Math.round(w * 2) / state.view.scale; 5737 5738 // Applies to opposite side 5739 if (mxEvent.isControlDown(me.getEvent())) 5740 { 5741 state.style[mxConstants.STYLE_STARTSIZE] = state.style[mxConstants.STYLE_ENDSIZE]; 5742 } 5743 5744 // Snaps to start geometry 5745 if (!mxEvent.isAltDown(me.getEvent())) 5746 { 5747 if (Math.abs(parseFloat(state.style[mxConstants.STYLE_ENDSIZE]) - parseFloat(state.style[mxConstants.STYLE_STARTSIZE])) < tol / 6) 5748 { 5749 state.style[mxConstants.STYLE_ENDSIZE] = state.style[mxConstants.STYLE_STARTSIZE]; 5750 } 5751 } 5752 })); 5753 5754 handles.push(createEdgeHandle(state, ['startWidth', 'endWidth', mxConstants.STYLE_STARTSIZE, mxConstants.STYLE_ENDSIZE], false, function(dist, nx, ny, p0, p1) 5755 { 5756 var w = (state.shape.getEndArrowWidth() - state.shape.strokewidth) * state.view.scale; 5757 var l = mxUtils.getNumber(state.style, mxConstants.STYLE_ENDSIZE, mxConstants.ARROW_SIZE / 5) * 3 * state.view.scale; 5758 5759 return new mxPoint(p0.x + nx * (l + state.shape.strokewidth * state.view.scale) - ny * w / 2, 5760 p0.y + ny * (l + state.shape.strokewidth * state.view.scale) + nx * w / 2); 5761 }, function(dist, nx, ny, p0, p1, pt, me) 5762 { 5763 var w = Math.sqrt(mxUtils.ptSegDistSq(p0.x, p0.y, p1.x, p1.y, pt.x, pt.y)); 5764 var l = mxUtils.ptLineDist(p0.x, p0.y, p0.x + ny, p0.y - nx, pt.x, pt.y); 5765 5766 state.style[mxConstants.STYLE_ENDSIZE] = Math.round((l - state.shape.strokewidth) * 100 / 3) / 100 / state.view.scale; 5767 state.style['endWidth'] = Math.max(0, Math.round(w * 2) - state.shape.getEdgeWidth()) / state.view.scale; 5768 5769 // Applies to opposite side 5770 if (mxEvent.isControlDown(me.getEvent())) 5771 { 5772 state.style[mxConstants.STYLE_STARTSIZE] = state.style[mxConstants.STYLE_ENDSIZE]; 5773 state.style['startWidth'] = state.style['endWidth']; 5774 } 5775 5776 // Snaps to start geometry 5777 if (!mxEvent.isAltDown(me.getEvent())) 5778 { 5779 if (Math.abs(parseFloat(state.style[mxConstants.STYLE_ENDSIZE]) - parseFloat(state.style[mxConstants.STYLE_STARTSIZE])) < tol / 6) 5780 { 5781 state.style[mxConstants.STYLE_ENDSIZE] = state.style[mxConstants.STYLE_STARTSIZE]; 5782 } 5783 5784 if (Math.abs(parseFloat(state.style['endWidth']) - parseFloat(state.style['startWidth'])) < tol) 5785 { 5786 state.style['endWidth'] = state.style['startWidth']; 5787 } 5788 } 5789 })); 5790 } 5791 5792 return handles; 5793 }, 5794 'swimlane': function(state) 5795 { 5796 var handles = []; 5797 5798 if (mxUtils.getValue(state.style, mxConstants.STYLE_ROUNDED)) 5799 { 5800 var size = parseFloat(mxUtils.getValue(state.style, mxConstants.STYLE_STARTSIZE, mxConstants.DEFAULT_STARTSIZE)); 5801 handles.push(createArcHandle(state, size / 2)); 5802 } 5803 5804 // Start size handle must be last item in handles for hover to work in tables (see mouse event handler in Graph) 5805 handles.push(createHandle(state, [mxConstants.STYLE_STARTSIZE], function(bounds) 5806 { 5807 var size = parseFloat(mxUtils.getValue(state.style, mxConstants.STYLE_STARTSIZE, mxConstants.DEFAULT_STARTSIZE)); 5808 5809 if (mxUtils.getValue(state.style, mxConstants.STYLE_HORIZONTAL, 1) == 1) 5810 { 5811 return new mxPoint(bounds.getCenterX(), bounds.y + Math.max(0, Math.min(bounds.height, size))); 5812 } 5813 else 5814 { 5815 return new mxPoint(bounds.x + Math.max(0, Math.min(bounds.width, size)), bounds.getCenterY()); 5816 } 5817 }, function(bounds, pt) 5818 { 5819 state.style[mxConstants.STYLE_STARTSIZE] = 5820 (mxUtils.getValue(this.state.style, mxConstants.STYLE_HORIZONTAL, 1) == 1) ? 5821 Math.round(Math.max(0, Math.min(bounds.height, pt.y - bounds.y))) : 5822 Math.round(Math.max(0, Math.min(bounds.width, pt.x - bounds.x))); 5823 }, false, null, function(me) 5824 { 5825 if (mxEvent.isControlDown(me.getEvent())) 5826 { 5827 var graph = state.view.graph; 5828 5829 if (graph.isTableRow(state.cell) || graph.isTableCell(state.cell)) 5830 { 5831 var dir = graph.getSwimlaneDirection(state.style); 5832 var parent = graph.model.getParent(state.cell); 5833 var cells = graph.model.getChildCells(parent, true); 5834 var temp = []; 5835 5836 for (var i = 0; i < cells.length; i++) 5837 { 5838 // Finds siblings with the same direction and to set start size 5839 if (cells[i] != state.cell && graph.isSwimlane(cells[i]) && 5840 graph.getSwimlaneDirection(graph.getCurrentCellStyle( 5841 cells[i])) == dir) 5842 { 5843 temp.push(cells[i]); 5844 } 5845 } 5846 5847 graph.setCellStyles(mxConstants.STYLE_STARTSIZE, 5848 state.style[mxConstants.STYLE_STARTSIZE], temp); 5849 } 5850 } 5851 })); 5852 5853 return handles; 5854 }, 5855 'label': createArcHandleFunction(), 5856 'ext': createArcHandleFunction(), 5857 'rectangle': createArcHandleFunction(), 5858 'triangle': createArcHandleFunction(), 5859 'rhombus': createArcHandleFunction(), 5860 'umlLifeline': function(state) 5861 { 5862 return [createHandle(state, ['size'], function(bounds) 5863 { 5864 var size = Math.max(0, Math.min(bounds.height, parseFloat(mxUtils.getValue(this.state.style, 'size', UmlLifeline.prototype.size)))); 5865 5866 return new mxPoint(bounds.getCenterX(), bounds.y + size); 5867 }, function(bounds, pt) 5868 { 5869 this.state.style['size'] = Math.round(Math.max(0, Math.min(bounds.height, pt.y - bounds.y))); 5870 }, false)]; 5871 }, 5872 'umlFrame': function(state) 5873 { 5874 var handles = [createHandle(state, ['width', 'height'], function(bounds) 5875 { 5876 var w0 = Math.max(UmlFrame.prototype.corner, Math.min(bounds.width, mxUtils.getValue(this.state.style, 'width', UmlFrame.prototype.width))); 5877 var h0 = Math.max(UmlFrame.prototype.corner * 1.5, Math.min(bounds.height, mxUtils.getValue(this.state.style, 'height', UmlFrame.prototype.height))); 5878 5879 return new mxPoint(bounds.x + w0, bounds.y + h0); 5880 }, function(bounds, pt) 5881 { 5882 this.state.style['width'] = Math.round(Math.max(UmlFrame.prototype.corner, Math.min(bounds.width, pt.x - bounds.x))); 5883 this.state.style['height'] = Math.round(Math.max(UmlFrame.prototype.corner * 1.5, Math.min(bounds.height, pt.y - bounds.y))); 5884 }, false)]; 5885 5886 return handles; 5887 }, 5888 'process': function(state) 5889 { 5890 var handles = [createHandle(state, ['size'], function(bounds) 5891 { 5892 5893 var fixed = mxUtils.getValue(this.state.style, 'fixedSize', '0') != '0'; 5894 var size = parseFloat(mxUtils.getValue(this.state.style, 'size', ProcessShape.prototype.size)); 5895 5896 return (fixed) ? new mxPoint(bounds.x + size, bounds.y + bounds.height / 4) : new mxPoint(bounds.x + bounds.width * size, bounds.y + bounds.height / 4); 5897 }, function(bounds, pt) 5898 { 5899 var fixed = mxUtils.getValue(this.state.style, 'fixedSize', '0') != '0'; 5900 var size = (fixed) ? Math.max(0, Math.min(bounds.width * 0.5, (pt.x - bounds.x))) : Math.max(0, Math.min(0.5, (pt.x - bounds.x) / bounds.width)); 5901 this.state.style['size'] = size; 5902 }, false)]; 5903 5904 if (mxUtils.getValue(state.style, mxConstants.STYLE_ROUNDED, false)) 5905 { 5906 handles.push(createArcHandle(state)); 5907 } 5908 5909 return handles; 5910 }, 5911 'cross': function(state) 5912 { 5913 return [createHandle(state, ['size'], function(bounds) 5914 { 5915 var m = Math.min(bounds.width, bounds.height); 5916 var size = Math.max(0, Math.min(1, mxUtils.getValue(this.state.style, 'size', CrossShape.prototype.size))) * m / 2; 5917 5918 return new mxPoint(bounds.getCenterX() - size, bounds.getCenterY() - size); 5919 }, function(bounds, pt) 5920 { 5921 var m = Math.min(bounds.width, bounds.height); 5922 this.state.style['size'] = Math.max(0, Math.min(1, Math.min((Math.max(0, bounds.getCenterY() - pt.y) / m) * 2, 5923 (Math.max(0, bounds.getCenterX() - pt.x) / m) * 2))); 5924 })]; 5925 }, 5926 'note': function(state) 5927 { 5928 return [createHandle(state, ['size'], function(bounds) 5929 { 5930 var size = Math.max(0, Math.min(bounds.width, Math.min(bounds.height, parseFloat( 5931 mxUtils.getValue(this.state.style, 'size', NoteShape.prototype.size))))); 5932 5933 return new mxPoint(bounds.x + bounds.width - size, bounds.y + size); 5934 }, function(bounds, pt) 5935 { 5936 this.state.style['size'] = Math.round(Math.max(0, Math.min(Math.min(bounds.width, bounds.x + bounds.width - pt.x), 5937 Math.min(bounds.height, pt.y - bounds.y)))); 5938 })]; 5939 }, 5940 'note2': function(state) 5941 { 5942 return [createHandle(state, ['size'], function(bounds) 5943 { 5944 var size = Math.max(0, Math.min(bounds.width, Math.min(bounds.height, parseFloat( 5945 mxUtils.getValue(this.state.style, 'size', NoteShape2.prototype.size))))); 5946 5947 return new mxPoint(bounds.x + bounds.width - size, bounds.y + size); 5948 }, function(bounds, pt) 5949 { 5950 this.state.style['size'] = Math.round(Math.max(0, Math.min(Math.min(bounds.width, bounds.x + bounds.width - pt.x), 5951 Math.min(bounds.height, pt.y - bounds.y)))); 5952 })]; 5953 }, 5954 'manualInput': function(state) 5955 { 5956 var handles = [createHandle(state, ['size'], function(bounds) 5957 { 5958 var size = Math.max(0, Math.min(bounds.height, mxUtils.getValue(this.state.style, 'size', ManualInputShape.prototype.size))); 5959 5960 return new mxPoint(bounds.x + bounds.width / 4, bounds.y + size * 3 / 4); 5961 }, function(bounds, pt) 5962 { 5963 this.state.style['size'] = Math.round(Math.max(0, Math.min(bounds.height, (pt.y - bounds.y) * 4 / 3))); 5964 }, false)]; 5965 5966 if (mxUtils.getValue(state.style, mxConstants.STYLE_ROUNDED, false)) 5967 { 5968 handles.push(createArcHandle(state)); 5969 } 5970 5971 return handles; 5972 }, 5973 'dataStorage': function(state) 5974 { 5975 return [createHandle(state, ['size'], function(bounds) 5976 { 5977 var fixed = mxUtils.getValue(this.state.style, 'fixedSize', '0') != '0'; 5978 var size = parseFloat(mxUtils.getValue(this.state.style, 'size', (fixed) ? DataStorageShape.prototype.fixedSize : DataStorageShape.prototype.size)); 5979 5980 return new mxPoint(bounds.x + bounds.width - size * ((fixed) ? 1 : bounds.width), bounds.getCenterY()); 5981 }, function(bounds, pt) 5982 { 5983 var fixed = mxUtils.getValue(this.state.style, 'fixedSize', '0') != '0'; 5984 var size = (fixed) ? Math.max(0, Math.min(bounds.width, (bounds.x + bounds.width - pt.x))) : Math.max(0, Math.min(1, (bounds.x + bounds.width - pt.x) / bounds.width)); 5985 5986 this.state.style['size'] = size; 5987 }, false)]; 5988 }, 5989 'callout': function(state) 5990 { 5991 var handles = [createHandle(state, ['size', 'position'], function(bounds) 5992 { 5993 var size = Math.max(0, Math.min(bounds.height, mxUtils.getValue(this.state.style, 'size', CalloutShape.prototype.size))); 5994 var position = Math.max(0, Math.min(1, mxUtils.getValue(this.state.style, 'position', CalloutShape.prototype.position))); 5995 var base = Math.max(0, Math.min(bounds.width, mxUtils.getValue(this.state.style, 'base', CalloutShape.prototype.base))); 5996 5997 return new mxPoint(bounds.x + position * bounds.width, bounds.y + bounds.height - size); 5998 }, function(bounds, pt) 5999 { 6000 var base = Math.max(0, Math.min(bounds.width, mxUtils.getValue(this.state.style, 'base', CalloutShape.prototype.base))); 6001 this.state.style['size'] = Math.round(Math.max(0, Math.min(bounds.height, bounds.y + bounds.height - pt.y))); 6002 this.state.style['position'] = Math.round(Math.max(0, Math.min(1, (pt.x - bounds.x) / bounds.width)) * 100) / 100; 6003 }, false), createHandle(state, ['position2'], function(bounds) 6004 { 6005 var position2 = Math.max(0, Math.min(1, mxUtils.getValue(this.state.style, 'position2', CalloutShape.prototype.position2))); 6006 6007 return new mxPoint(bounds.x + position2 * bounds.width, bounds.y + bounds.height); 6008 }, function(bounds, pt) 6009 { 6010 this.state.style['position2'] = Math.round(Math.max(0, Math.min(1, (pt.x - bounds.x) / bounds.width)) * 100) / 100; 6011 }, false), createHandle(state, ['base'], function(bounds) 6012 { 6013 var size = Math.max(0, Math.min(bounds.height, mxUtils.getValue(this.state.style, 'size', CalloutShape.prototype.size))); 6014 var position = Math.max(0, Math.min(1, mxUtils.getValue(this.state.style, 'position', CalloutShape.prototype.position))); 6015 var base = Math.max(0, Math.min(bounds.width, mxUtils.getValue(this.state.style, 'base', CalloutShape.prototype.base))); 6016 6017 return new mxPoint(bounds.x + Math.min(bounds.width, position * bounds.width + base), bounds.y + bounds.height - size); 6018 }, function(bounds, pt) 6019 { 6020 var position = Math.max(0, Math.min(1, mxUtils.getValue(this.state.style, 'position', CalloutShape.prototype.position))); 6021 6022 this.state.style['base'] = Math.round(Math.max(0, Math.min(bounds.width, pt.x - bounds.x - position * bounds.width))); 6023 }, false)]; 6024 6025 if (mxUtils.getValue(state.style, mxConstants.STYLE_ROUNDED, false)) 6026 { 6027 handles.push(createArcHandle(state)); 6028 } 6029 6030 return handles; 6031 }, 6032 'internalStorage': function(state) 6033 { 6034 var handles = [createHandle(state, ['dx', 'dy'], function(bounds) 6035 { 6036 var dx = Math.max(0, Math.min(bounds.width, mxUtils.getValue(this.state.style, 'dx', InternalStorageShape.prototype.dx))); 6037 var dy = Math.max(0, Math.min(bounds.height, mxUtils.getValue(this.state.style, 'dy', InternalStorageShape.prototype.dy))); 6038 6039 return new mxPoint(bounds.x + dx, bounds.y + dy); 6040 }, function(bounds, pt) 6041 { 6042 this.state.style['dx'] = Math.round(Math.max(0, Math.min(bounds.width, pt.x - bounds.x))); 6043 this.state.style['dy'] = Math.round(Math.max(0, Math.min(bounds.height, pt.y - bounds.y))); 6044 }, false)]; 6045 6046 if (mxUtils.getValue(state.style, mxConstants.STYLE_ROUNDED, false)) 6047 { 6048 handles.push(createArcHandle(state)); 6049 } 6050 6051 return handles; 6052 }, 6053 'module': function(state) 6054 { 6055 var handles = [createHandle(state, ['jettyWidth', 'jettyHeight'], function(bounds) 6056 { 6057 var dx = Math.max(0, Math.min(bounds.width, mxUtils.getValue(this.state.style, 'jettyWidth', ModuleShape.prototype.jettyWidth))); 6058 var dy = Math.max(0, Math.min(bounds.height, mxUtils.getValue(this.state.style, 'jettyHeight', ModuleShape.prototype.jettyHeight))); 6059 6060 return new mxPoint(bounds.x + dx / 2, bounds.y + dy * 2); 6061 }, function(bounds, pt) 6062 { 6063 this.state.style['jettyWidth'] = Math.round(Math.max(0, Math.min(bounds.width, pt.x - bounds.x)) * 2); 6064 this.state.style['jettyHeight'] = Math.round(Math.max(0, Math.min(bounds.height, pt.y - bounds.y)) / 2); 6065 })]; 6066 6067 return handles; 6068 }, 6069 'corner': function(state) 6070 { 6071 return [createHandle(state, ['dx', 'dy'], function(bounds) 6072 { 6073 var dx = Math.max(0, Math.min(bounds.width, mxUtils.getValue(this.state.style, 'dx', CornerShape.prototype.dx))); 6074 var dy = Math.max(0, Math.min(bounds.height, mxUtils.getValue(this.state.style, 'dy', CornerShape.prototype.dy))); 6075 6076 return new mxPoint(bounds.x + dx, bounds.y + dy); 6077 }, function(bounds, pt) 6078 { 6079 this.state.style['dx'] = Math.round(Math.max(0, Math.min(bounds.width, pt.x - bounds.x))); 6080 this.state.style['dy'] = Math.round(Math.max(0, Math.min(bounds.height, pt.y - bounds.y))); 6081 }, false)]; 6082 }, 6083 'tee': function(state) 6084 { 6085 return [createHandle(state, ['dx', 'dy'], function(bounds) 6086 { 6087 var dx = Math.max(0, Math.min(bounds.width, mxUtils.getValue(this.state.style, 'dx', TeeShape.prototype.dx))); 6088 var dy = Math.max(0, Math.min(bounds.height, mxUtils.getValue(this.state.style, 'dy', TeeShape.prototype.dy))); 6089 6090 return new mxPoint(bounds.x + (bounds.width + dx) / 2, bounds.y + dy); 6091 }, function(bounds, pt) 6092 { 6093 this.state.style['dx'] = Math.round(Math.max(0, Math.min(bounds.width / 2, (pt.x - bounds.x - bounds.width / 2)) * 2)); 6094 this.state.style['dy'] = Math.round(Math.max(0, Math.min(bounds.height, pt.y - bounds.y))); 6095 }, false)]; 6096 }, 6097 'singleArrow': createArrowHandleFunction(1), 6098 'doubleArrow': createArrowHandleFunction(0.5), 6099 'folder': function(state) 6100 { 6101 return [createHandle(state, ['tabWidth', 'tabHeight'], function(bounds) 6102 { 6103 var tw = Math.max(0, Math.min(bounds.width, mxUtils.getValue(this.state.style, 'tabWidth', FolderShape.prototype.tabWidth))); 6104 var th = Math.max(0, Math.min(bounds.height, mxUtils.getValue(this.state.style, 'tabHeight', FolderShape.prototype.tabHeight))); 6105 6106 if (mxUtils.getValue(this.state.style, 'tabPosition', FolderShape.prototype.tabPosition) == mxConstants.ALIGN_RIGHT) 6107 { 6108 tw = bounds.width - tw; 6109 } 6110 6111 return new mxPoint(bounds.x + tw, bounds.y + th); 6112 }, function(bounds, pt) 6113 { 6114 var tw = Math.max(0, Math.min(bounds.width, pt.x - bounds.x)); 6115 6116 if (mxUtils.getValue(this.state.style, 'tabPosition', FolderShape.prototype.tabPosition) == mxConstants.ALIGN_RIGHT) 6117 { 6118 tw = bounds.width - tw; 6119 } 6120 6121 this.state.style['tabWidth'] = Math.round(tw); 6122 this.state.style['tabHeight'] = Math.round(Math.max(0, Math.min(bounds.height, pt.y - bounds.y))); 6123 }, false)]; 6124 }, 6125 'document': function(state) 6126 { 6127 return [createHandle(state, ['size'], function(bounds) 6128 { 6129 var size = Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.state.style, 'size', DocumentShape.prototype.size)))); 6130 6131 return new mxPoint(bounds.x + 3 * bounds.width / 4, bounds.y + (1 - size) * bounds.height); 6132 }, function(bounds, pt) 6133 { 6134 this.state.style['size'] = Math.max(0, Math.min(1, (bounds.y + bounds.height - pt.y) / bounds.height)); 6135 }, false)]; 6136 }, 6137 'tape': function(state) 6138 { 6139 return [createHandle(state, ['size'], function(bounds) 6140 { 6141 var size = Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.state.style, 'size', TapeShape.prototype.size)))); 6142 6143 return new mxPoint(bounds.getCenterX(), bounds.y + size * bounds.height / 2); 6144 }, function(bounds, pt) 6145 { 6146 this.state.style['size'] = Math.max(0, Math.min(1, ((pt.y - bounds.y) / bounds.height) * 2)); 6147 }, false)]; 6148 }, 6149 'isoCube2' : function(state) 6150 { 6151 return [createHandle(state, ['isoAngle'], function(bounds) 6152 { 6153 var isoAngle = Math.max(0.01, Math.min(94, parseFloat(mxUtils.getValue(this.state.style, 'isoAngle', IsoCubeShape2.isoAngle)))) * Math.PI / 200 ; 6154 var isoH = Math.min(bounds.width * Math.tan(isoAngle), bounds.height * 0.5); 6155 6156 return new mxPoint(bounds.x, bounds.y + isoH); 6157 }, function(bounds, pt) 6158 { 6159 this.state.style['isoAngle'] = Math.max(0, (pt.y - bounds.y) * 50 / bounds.height); 6160 }, true)]; 6161 }, 6162 'cylinder2' : createCylinderHandleFunction(CylinderShape.prototype.size), 6163 'cylinder3' : createCylinderHandleFunction(CylinderShape3.prototype.size), 6164 'offPageConnector': function(state) 6165 { 6166 return [createHandle(state, ['size'], function(bounds) 6167 { 6168 var size = Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.state.style, 'size', OffPageConnectorShape.prototype.size)))); 6169 6170 return new mxPoint(bounds.getCenterX(), bounds.y + (1 - size) * bounds.height); 6171 }, function(bounds, pt) 6172 { 6173 this.state.style['size'] = Math.max(0, Math.min(1, (bounds.y + bounds.height - pt.y) / bounds.height)); 6174 }, false)]; 6175 }, 6176 'mxgraph.basic.rect': function(state) 6177 { 6178 var handles = [Graph.createHandle(state, ['size'], function(bounds) 6179 { 6180 var size = Math.max(0, Math.min(bounds.width / 2, bounds.height / 2, parseFloat(mxUtils.getValue(this.state.style, 'size', this.size)))); 6181 6182 return new mxPoint(bounds.x + size, bounds.y + size); 6183 }, function(bounds, pt) 6184 { 6185 this.state.style['size'] = Math.round(100 * Math.max(0, Math.min(bounds.height / 2, bounds.width / 2, pt.x - bounds.x))) / 100; 6186 })]; 6187 6188 var handle2 = Graph.createHandle(state, ['indent'], function(bounds) 6189 { 6190 var dx2 = Math.max(0, Math.min(100, parseFloat(mxUtils.getValue(this.state.style, 'indent', this.dx2)))); 6191 6192 return new mxPoint(bounds.x + bounds.width * 0.75, bounds.y + dx2 * bounds.height / 200); 6193 }, function(bounds, pt) 6194 { 6195 this.state.style['indent'] = Math.round(100 * Math.max(0, Math.min(100, 200 * (pt.y - bounds.y) / bounds.height))) / 100; 6196 }); 6197 6198 handles.push(handle2); 6199 6200 return handles; 6201 }, 6202 'step': createDisplayHandleFunction(StepShape.prototype.size, true, null, true, StepShape.prototype.fixedSize), 6203 'hexagon': createDisplayHandleFunction(HexagonShape.prototype.size, true, 0.5, true, HexagonShape.prototype.fixedSize), 6204 'curlyBracket': createDisplayHandleFunction(CurlyBracketShape.prototype.size, false), 6205 'display': createDisplayHandleFunction(DisplayShape.prototype.size, false), 6206 'cube': createCubeHandleFunction(1, CubeShape.prototype.size, false), 6207 'card': createCubeHandleFunction(0.5, CardShape.prototype.size, true), 6208 'loopLimit': createCubeHandleFunction(0.5, LoopLimitShape.prototype.size, true), 6209 'trapezoid': createTrapezoidHandleFunction(0.5, TrapezoidShape.prototype.size, TrapezoidShape.prototype.fixedSize), 6210 'parallelogram': createTrapezoidHandleFunction(1, ParallelogramShape.prototype.size, ParallelogramShape.prototype.fixedSize) 6211 }; 6212 6213 // Exposes custom handles 6214 Graph.createHandle = createHandle; 6215 Graph.handleFactory = handleFactory; 6216 6217 var vertexHandlerCreateCustomHandles = mxVertexHandler.prototype.createCustomHandles; 6218 6219 mxVertexHandler.prototype.createCustomHandles = function() 6220 { 6221 var handles = vertexHandlerCreateCustomHandles.apply(this, arguments); 6222 6223 if (this.graph.isCellRotatable(this.state.cell)) 6224 // LATER: Make locked state independent of rotatable flag, fix toggle if default is false 6225 //if (this.graph.isCellResizable(this.state.cell) || this.graph.isCellMovable(this.state.cell)) 6226 { 6227 var name = this.state.style['shape']; 6228 6229 if (mxCellRenderer.defaultShapes[name] == null && 6230 mxStencilRegistry.getStencil(name) == null) 6231 { 6232 name = mxConstants.SHAPE_RECTANGLE; 6233 } 6234 else if (this.state.view.graph.isSwimlane(this.state.cell)) 6235 { 6236 name = mxConstants.SHAPE_SWIMLANE; 6237 } 6238 6239 var fn = handleFactory[name]; 6240 6241 if (fn == null && this.state.shape != null && this.state.shape.isRoundable()) 6242 { 6243 fn = handleFactory[mxConstants.SHAPE_RECTANGLE]; 6244 } 6245 6246 if (fn != null) 6247 { 6248 var temp = fn(this.state); 6249 6250 if (temp != null) 6251 { 6252 if (handles == null) 6253 { 6254 handles = temp; 6255 } 6256 else 6257 { 6258 handles = handles.concat(temp); 6259 } 6260 } 6261 } 6262 } 6263 6264 return handles; 6265 }; 6266 6267 mxEdgeHandler.prototype.createCustomHandles = function() 6268 { 6269 var name = this.state.style['shape']; 6270 6271 if (mxCellRenderer.defaultShapes[name] == null && 6272 mxStencilRegistry.getStencil(name) == null) 6273 { 6274 name = mxConstants.SHAPE_CONNECTOR; 6275 } 6276 6277 var fn = handleFactory[name]; 6278 6279 if (fn != null) 6280 { 6281 return fn(this.state); 6282 } 6283 6284 return null; 6285 } 6286 } 6287 else 6288 { 6289 // Dummy entries to avoid NPE in embed mode 6290 Graph.createHandle = function() {}; 6291 Graph.handleFactory = {}; 6292 } 6293 6294 var isoHVector = new mxPoint(1, 0); 6295 var isoVVector = new mxPoint(1, 0); 6296 6297 var alpha1 = mxUtils.toRadians(-30); 6298 6299 var cos1 = Math.cos(alpha1); 6300 var sin1 = Math.sin(alpha1); 6301 6302 isoHVector = mxUtils.getRotatedPoint(isoHVector, cos1, sin1); 6303 6304 var alpha2 = mxUtils.toRadians(-150); 6305 6306 var cos2 = Math.cos(alpha2); 6307 var sin2 = Math.sin(alpha2); 6308 6309 isoVVector = mxUtils.getRotatedPoint(isoVVector, cos2, sin2); 6310 6311 mxEdgeStyle.IsometricConnector = function (state, source, target, points, result) 6312 { 6313 var view = state.view; 6314 var pt = (points != null && points.length > 0) ? points[0] : null; 6315 var pts = state.absolutePoints; 6316 var p0 = pts[0]; 6317 var pe = pts[pts.length-1]; 6318 6319 if (pt != null) 6320 { 6321 pt = view.transformControlPoint(state, pt); 6322 } 6323 6324 if (p0 == null) 6325 { 6326 if (source != null) 6327 { 6328 p0 = new mxPoint(source.getCenterX(), source.getCenterY()); 6329 } 6330 } 6331 6332 if (pe == null) 6333 { 6334 if (target != null) 6335 { 6336 pe = new mxPoint(target.getCenterX(), target.getCenterY()); 6337 } 6338 } 6339 6340 var a1 = isoHVector.x; 6341 var a2 = isoHVector.y; 6342 6343 var b1 = isoVVector.x; 6344 var b2 = isoVVector.y; 6345 6346 var elbow = mxUtils.getValue(state.style, 'elbow', 'horizontal') == 'horizontal'; 6347 6348 if (pe != null && p0 != null) 6349 { 6350 var last = p0; 6351 6352 function isoLineTo(x, y, ignoreFirst) 6353 { 6354 var c1 = x - last.x; 6355 var c2 = y - last.y; 6356 6357 // Solves for isometric base vectors 6358 var h = (b2 * c1 - b1 * c2) / (a1 * b2 - a2 * b1); 6359 var v = (a2 * c1 - a1 * c2) / (a2 * b1 - a1 * b2); 6360 6361 if (elbow) 6362 { 6363 if (ignoreFirst) 6364 { 6365 last = new mxPoint(last.x + a1 * h, last.y + a2 * h); 6366 result.push(last); 6367 } 6368 6369 last = new mxPoint(last.x + b1 * v, last.y + b2 * v); 6370 result.push(last); 6371 } 6372 else 6373 { 6374 if (ignoreFirst) 6375 { 6376 last = new mxPoint(last.x + b1 * v, last.y + b2 * v); 6377 result.push(last); 6378 } 6379 6380 last = new mxPoint(last.x + a1 * h, last.y + a2 * h); 6381 result.push(last); 6382 } 6383 }; 6384 6385 if (pt == null) 6386 { 6387 pt = new mxPoint(p0.x + (pe.x - p0.x) / 2, p0.y + (pe.y - p0.y) / 2); 6388 } 6389 6390 isoLineTo(pt.x, pt.y, true); 6391 isoLineTo(pe.x, pe.y, false); 6392 } 6393 }; 6394 6395 mxStyleRegistry.putValue('isometricEdgeStyle', mxEdgeStyle.IsometricConnector); 6396 6397 var graphCreateEdgeHandler = Graph.prototype.createEdgeHandler; 6398 Graph.prototype.createEdgeHandler = function(state, edgeStyle) 6399 { 6400 if (edgeStyle == mxEdgeStyle.IsometricConnector) 6401 { 6402 var handler = new mxElbowEdgeHandler(state); 6403 handler.snapToTerminals = false; 6404 6405 return handler; 6406 } 6407 6408 return graphCreateEdgeHandler.apply(this, arguments); 6409 }; 6410 6411 // Defines connection points for all shapes 6412 IsoRectangleShape.prototype.constraints = []; 6413 6414 IsoCubeShape.prototype.getConstraints = function(style, w, h) 6415 { 6416 var constr = []; 6417 var tan30 = Math.tan(mxUtils.toRadians(30)); 6418 var tan30Dx = (0.5 - tan30) / 2; 6419 var m = Math.min(w, h / (0.5 + tan30)); 6420 var dx = (w - m) / 2; 6421 var dy = (h - m) / 2; 6422 6423 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, dx, dy + 0.25 * m)); 6424 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, dx + 0.5 * m, dy + m * tan30Dx)); 6425 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, dx + m, dy + 0.25 * m)); 6426 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, dx + m, dy + 0.75 * m)); 6427 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, dx + 0.5 * m, dy + (1 - tan30Dx) * m)); 6428 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, dx, dy + 0.75 * m)); 6429 6430 return (constr); 6431 }; 6432 6433 IsoCubeShape2.prototype.getConstraints = function(style, w, h) 6434 { 6435 var constr = []; 6436 var isoAngle = Math.max(0.01, Math.min(94, parseFloat(mxUtils.getValue(this.style, 'isoAngle', this.isoAngle)))) * Math.PI / 200 ; 6437 var isoH = Math.min(w * Math.tan(isoAngle), h * 0.5); 6438 6439 constr.push(new mxConnectionConstraint(new mxPoint(0.5, 0), false)); 6440 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w, isoH)); 6441 constr.push(new mxConnectionConstraint(new mxPoint(1, 0.5), false)); 6442 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w, h - isoH)); 6443 constr.push(new mxConnectionConstraint(new mxPoint(0.5, 1), false)); 6444 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, 0, h - isoH)); 6445 constr.push(new mxConnectionConstraint(new mxPoint(0, 0.5), false)); 6446 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, 0, isoH)); 6447 6448 return (constr); 6449 } 6450 6451 CalloutShape.prototype.getConstraints = function(style, w, h) 6452 { 6453 var constr = []; 6454 var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2; 6455 var s = Math.max(0, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); 6456 var dx = w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'position', this.position)))); 6457 var dx2 = w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'position2', this.position2)))); 6458 var base = Math.max(0, Math.min(w, parseFloat(mxUtils.getValue(this.style, 'base', this.base)))); 6459 6460 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false)); 6461 constr.push(new mxConnectionConstraint(new mxPoint(0.25, 0), false)); 6462 constr.push(new mxConnectionConstraint(new mxPoint(0.5, 0), false)); 6463 constr.push(new mxConnectionConstraint(new mxPoint(0.75, 0), false)); 6464 constr.push(new mxConnectionConstraint(new mxPoint(1, 0), false)); 6465 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w, (h - s) * 0.5)); 6466 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w, h - s)); 6467 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, dx2, h)); 6468 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, 0, h - s)); 6469 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, 0, (h - s) * 0.5)); 6470 6471 if (w >= s * 2) 6472 { 6473 constr.push(new mxConnectionConstraint(new mxPoint(0.5, 0), false)); 6474 } 6475 6476 return (constr); 6477 }; 6478 6479 mxRectangleShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0), true), 6480 new mxConnectionConstraint(new mxPoint(0.25, 0), true), 6481 new mxConnectionConstraint(new mxPoint(0.5, 0), true), 6482 new mxConnectionConstraint(new mxPoint(0.75, 0), true), 6483 new mxConnectionConstraint(new mxPoint(1, 0), true), 6484 new mxConnectionConstraint(new mxPoint(0, 0.25), true), 6485 new mxConnectionConstraint(new mxPoint(0, 0.5), true), 6486 new mxConnectionConstraint(new mxPoint(0, 0.75), true), 6487 new mxConnectionConstraint(new mxPoint(1, 0.25), true), 6488 new mxConnectionConstraint(new mxPoint(1, 0.5), true), 6489 new mxConnectionConstraint(new mxPoint(1, 0.75), true), 6490 new mxConnectionConstraint(new mxPoint(0, 1), true), 6491 new mxConnectionConstraint(new mxPoint(0.25, 1), true), 6492 new mxConnectionConstraint(new mxPoint(0.5, 1), true), 6493 new mxConnectionConstraint(new mxPoint(0.75, 1), true), 6494 new mxConnectionConstraint(new mxPoint(1, 1), true)]; 6495 mxEllipse.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0), true), new mxConnectionConstraint(new mxPoint(1, 0), true), 6496 new mxConnectionConstraint(new mxPoint(0, 1), true), new mxConnectionConstraint(new mxPoint(1, 1), true), 6497 new mxConnectionConstraint(new mxPoint(0.5, 0), true), new mxConnectionConstraint(new mxPoint(0.5, 1), true), 6498 new mxConnectionConstraint(new mxPoint(0, 0.5), true), new mxConnectionConstraint(new mxPoint(1, 0.5))]; 6499 PartialRectangleShape.prototype.constraints = mxRectangleShape.prototype.constraints; 6500 mxImageShape.prototype.constraints = mxRectangleShape.prototype.constraints; 6501 mxSwimlane.prototype.constraints = mxRectangleShape.prototype.constraints; 6502 PlusShape.prototype.constraints = mxRectangleShape.prototype.constraints; 6503 mxLabel.prototype.constraints = mxRectangleShape.prototype.constraints; 6504 6505 NoteShape.prototype.getConstraints = function(style, w, h) 6506 { 6507 var constr = []; 6508 var s = Math.max(0, Math.min(w, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size))))); 6509 6510 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false)); 6511 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, (w - s) * 0.5, 0)); 6512 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w - s, 0)); 6513 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w - s * 0.5, s * 0.5)); 6514 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w, s)); 6515 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w, (h + s) * 0.5 )); 6516 constr.push(new mxConnectionConstraint(new mxPoint(1, 1), false)); 6517 constr.push(new mxConnectionConstraint(new mxPoint(0.5, 1), false)); 6518 constr.push(new mxConnectionConstraint(new mxPoint(0, 1), false)); 6519 constr.push(new mxConnectionConstraint(new mxPoint(0, 0.5), false)); 6520 6521 if (w >= s * 2) 6522 { 6523 constr.push(new mxConnectionConstraint(new mxPoint(0.5, 0), false)); 6524 } 6525 6526 return (constr); 6527 }; 6528 6529 CardShape.prototype.getConstraints = function(style, w, h) 6530 { 6531 var constr = []; 6532 var s = Math.max(0, Math.min(w, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size))))); 6533 6534 constr.push(new mxConnectionConstraint(new mxPoint(1, 0), false)); 6535 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, (w + s) * 0.5, 0)); 6536 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, s, 0)); 6537 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, s * 0.5, s * 0.5)); 6538 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, 0, s)); 6539 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, 0, (h + s) * 0.5 )); 6540 constr.push(new mxConnectionConstraint(new mxPoint(0, 1), false)); 6541 constr.push(new mxConnectionConstraint(new mxPoint(0.5, 1), false)); 6542 constr.push(new mxConnectionConstraint(new mxPoint(1, 1), false)); 6543 constr.push(new mxConnectionConstraint(new mxPoint(1, 0.5), false)); 6544 6545 if (w >= s * 2) 6546 { 6547 constr.push(new mxConnectionConstraint(new mxPoint(0.5, 0), false)); 6548 } 6549 6550 return (constr); 6551 }; 6552 6553 CubeShape.prototype.getConstraints = function(style, w, h) 6554 { 6555 var constr = []; 6556 var s = Math.max(0, Math.min(w, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size))))); 6557 6558 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false)); 6559 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, (w - s) * 0.5, 0)); 6560 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w - s, 0)); 6561 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w - s * 0.5, s * 0.5)); 6562 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w, s)); 6563 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w, (h + s) * 0.5)); 6564 constr.push(new mxConnectionConstraint(new mxPoint(1, 1), false)); 6565 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, (w + s) * 0.5, h)); 6566 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, s, h)); 6567 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, s * 0.5, h - s * 0.5)); 6568 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, 0, h - s)); 6569 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, 0, (h - s) * 0.5)); 6570 6571 return (constr); 6572 }; 6573 6574 CylinderShape3.prototype.getConstraints = function(style, w, h) 6575 { 6576 var constr = []; 6577 var s = Math.max(0, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); 6578 6579 constr.push(new mxConnectionConstraint(new mxPoint(0.5, 0), false)); 6580 constr.push(new mxConnectionConstraint(new mxPoint(0, 0.5), false)); 6581 constr.push(new mxConnectionConstraint(new mxPoint(0.5, 1), false)); 6582 constr.push(new mxConnectionConstraint(new mxPoint(1, 0.5), false)); 6583 6584 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, 0, s)); 6585 constr.push(new mxConnectionConstraint(new mxPoint(1, 0), false, null, 0, s)); 6586 constr.push(new mxConnectionConstraint(new mxPoint(1, 1), false, null, 0, -s)); 6587 constr.push(new mxConnectionConstraint(new mxPoint(0, 1), false, null, 0, -s)); 6588 6589 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, 0, s + (h * 0.5 - s) * 0.5)); 6590 constr.push(new mxConnectionConstraint(new mxPoint(1, 0), false, null, 0, s + (h * 0.5 - s) * 0.5)); 6591 constr.push(new mxConnectionConstraint(new mxPoint(1, 0), false, null, 0, h - s - (h * 0.5 - s) * 0.5)); 6592 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, 0, h - s - (h * 0.5 - s) * 0.5)); 6593 6594 constr.push(new mxConnectionConstraint(new mxPoint(0.145, 0), false, null, 0, s * 0.29)); 6595 constr.push(new mxConnectionConstraint(new mxPoint(0.855, 0), false, null, 0, s * 0.29)); 6596 constr.push(new mxConnectionConstraint(new mxPoint(0.855, 1), false, null, 0, -s * 0.29)); 6597 constr.push(new mxConnectionConstraint(new mxPoint(0.145, 1), false, null, 0, -s * 0.29)); 6598 6599 return (constr); 6600 }; 6601 6602 FolderShape.prototype.getConstraints = function(style, w, h) 6603 { 6604 var constr = []; 6605 var dx = Math.max(0, Math.min(w, parseFloat(mxUtils.getValue(this.style, 'tabWidth', this.tabWidth)))); 6606 var dy = Math.max(0, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'tabHeight', this.tabHeight)))); 6607 var tp = mxUtils.getValue(this.style, 'tabPosition', this.tabPosition); 6608 6609 if (tp == 'left') 6610 { 6611 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false)); 6612 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, dx * 0.5, 0)); 6613 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, dx, 0)); 6614 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, dx, dy)); 6615 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, (w + dx) * 0.5, dy)); 6616 } 6617 else 6618 { 6619 constr.push(new mxConnectionConstraint(new mxPoint(1, 0), false)); 6620 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w - dx * 0.5, 0)); 6621 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w - dx, 0)); 6622 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w - dx, dy)); 6623 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, (w - dx) * 0.5, dy)); 6624 } 6625 6626 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w, dy)); 6627 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w, (h - dy) * 0.25 + dy)); 6628 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w, (h - dy) * 0.5 + dy)); 6629 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w, (h - dy) * 0.75 + dy)); 6630 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w, h)); 6631 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, 0, dy)); 6632 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, 0, (h - dy) * 0.25 + dy)); 6633 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, 0, (h - dy) * 0.5 + dy)); 6634 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, 0, (h - dy) * 0.75 + dy)); 6635 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, 0, h)); 6636 constr.push(new mxConnectionConstraint(new mxPoint(0.25, 1), false)); 6637 constr.push(new mxConnectionConstraint(new mxPoint(0.5, 1), false)); 6638 constr.push(new mxConnectionConstraint(new mxPoint(0.75, 1), false)); 6639 6640 return (constr); 6641 } 6642 6643 InternalStorageShape.prototype.constraints = mxRectangleShape.prototype.constraints; 6644 DataStorageShape.prototype.constraints = mxRectangleShape.prototype.constraints; 6645 TapeDataShape.prototype.constraints = mxEllipse.prototype.constraints; 6646 OrEllipseShape.prototype.constraints = mxEllipse.prototype.constraints; 6647 SumEllipseShape.prototype.constraints = mxEllipse.prototype.constraints; 6648 LineEllipseShape.prototype.constraints = mxEllipse.prototype.constraints; 6649 ManualInputShape.prototype.constraints = mxRectangleShape.prototype.constraints; 6650 DelayShape.prototype.constraints = mxRectangleShape.prototype.constraints; 6651 6652 DisplayShape.prototype.getConstraints = function(style, w, h) 6653 { 6654 var constr = []; 6655 var dx = Math.min(w, h / 2); 6656 var s = Math.min(w - dx, Math.max(0, parseFloat(mxUtils.getValue(this.style, 'size', this.size))) * w); 6657 6658 constr.push(new mxConnectionConstraint(new mxPoint(0, 0.5), false, null)); 6659 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, s, 0)); 6660 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, (s + w - dx) * 0.5, 0)); 6661 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w - dx, 0)); 6662 constr.push(new mxConnectionConstraint(new mxPoint(1, 0.5), false, null)); 6663 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w - dx, h)); 6664 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, (s + w - dx) * 0.5, h)); 6665 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, s, h)); 6666 6667 return (constr); 6668 }; 6669 6670 ModuleShape.prototype.getConstraints = function(style, w, h) 6671 { 6672 var x0 = parseFloat(mxUtils.getValue(style, 'jettyWidth', ModuleShape.prototype.jettyWidth)) / 2; 6673 var dy = parseFloat(mxUtils.getValue(style, 'jettyHeight', ModuleShape.prototype.jettyHeight)); 6674 var constr = [new mxConnectionConstraint(new mxPoint(0, 0), false, null, x0), 6675 new mxConnectionConstraint(new mxPoint(0.25, 0), true), 6676 new mxConnectionConstraint(new mxPoint(0.5, 0), true), 6677 new mxConnectionConstraint(new mxPoint(0.75, 0), true), 6678 new mxConnectionConstraint(new mxPoint(1, 0), true), 6679 new mxConnectionConstraint(new mxPoint(1, 0.25), true), 6680 new mxConnectionConstraint(new mxPoint(1, 0.5), true), 6681 new mxConnectionConstraint(new mxPoint(1, 0.75), true), 6682 new mxConnectionConstraint(new mxPoint(0, 1), false, null, x0), 6683 new mxConnectionConstraint(new mxPoint(0.25, 1), true), 6684 new mxConnectionConstraint(new mxPoint(0.5, 1), true), 6685 new mxConnectionConstraint(new mxPoint(0.75, 1), true), 6686 new mxConnectionConstraint(new mxPoint(1, 1), true), 6687 new mxConnectionConstraint(new mxPoint(0, 0), false, null, 0, Math.min(h - 0.5 * dy, 1.5 * dy)), 6688 new mxConnectionConstraint(new mxPoint(0, 0), false, null, 0, Math.min(h - 0.5 * dy, 3.5 * dy))]; 6689 6690 if (h > 5 * dy) 6691 { 6692 constr.push(new mxConnectionConstraint(new mxPoint(0, 0.75), false, null, x0)); 6693 } 6694 6695 if (h > 8 * dy) 6696 { 6697 constr.push(new mxConnectionConstraint(new mxPoint(0, 0.5), false, null, x0)); 6698 } 6699 6700 if (h > 15 * dy) 6701 { 6702 constr.push(new mxConnectionConstraint(new mxPoint(0, 0.25), false, null, x0)); 6703 } 6704 6705 return constr; 6706 }; 6707 6708 LoopLimitShape.prototype.constraints = mxRectangleShape.prototype.constraints; 6709 OffPageConnectorShape.prototype.constraints = mxRectangleShape.prototype.constraints; 6710 mxCylinder.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.15, 0.05), false), 6711 new mxConnectionConstraint(new mxPoint(0.5, 0), true), 6712 new mxConnectionConstraint(new mxPoint(0.85, 0.05), false), 6713 new mxConnectionConstraint(new mxPoint(0, 0.3), true), 6714 new mxConnectionConstraint(new mxPoint(0, 0.5), true), 6715 new mxConnectionConstraint(new mxPoint(0, 0.7), true), 6716 new mxConnectionConstraint(new mxPoint(1, 0.3), true), 6717 new mxConnectionConstraint(new mxPoint(1, 0.5), true), 6718 new mxConnectionConstraint(new mxPoint(1, 0.7), true), 6719 new mxConnectionConstraint(new mxPoint(0.15, 0.95), false), 6720 new mxConnectionConstraint(new mxPoint(0.5, 1), true), 6721 new mxConnectionConstraint(new mxPoint(0.85, 0.95), false)]; 6722 UmlActorShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.25, 0.1), false), 6723 new mxConnectionConstraint(new mxPoint(0.5, 0), false), 6724 new mxConnectionConstraint(new mxPoint(0.75, 0.1), false), 6725 new mxConnectionConstraint(new mxPoint(0, 1/3), false), 6726 new mxConnectionConstraint(new mxPoint(0, 1), false), 6727 new mxConnectionConstraint(new mxPoint(1, 1/3), false), 6728 new mxConnectionConstraint(new mxPoint(1, 1), false), 6729 new mxConnectionConstraint(new mxPoint(0.5, 0.5), false)]; 6730 ComponentShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.25, 0), true), 6731 new mxConnectionConstraint(new mxPoint(0.5, 0), true), 6732 new mxConnectionConstraint(new mxPoint(0.75, 0), true), 6733 new mxConnectionConstraint(new mxPoint(0, 0.3), true), 6734 new mxConnectionConstraint(new mxPoint(0, 0.7), true), 6735 new mxConnectionConstraint(new mxPoint(1, 0.25), true), 6736 new mxConnectionConstraint(new mxPoint(1, 0.5), true), 6737 new mxConnectionConstraint(new mxPoint(1, 0.75), true), 6738 new mxConnectionConstraint(new mxPoint(0.25, 1), true), 6739 new mxConnectionConstraint(new mxPoint(0.5, 1), true), 6740 new mxConnectionConstraint(new mxPoint(0.75, 1), true)]; 6741 mxActor.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.5, 0), true), 6742 new mxConnectionConstraint(new mxPoint(0.25, 0.2), false), 6743 new mxConnectionConstraint(new mxPoint(0.1, 0.5), false), 6744 new mxConnectionConstraint(new mxPoint(0, 0.75), true), 6745 new mxConnectionConstraint(new mxPoint(0.75, 0.25), false), 6746 new mxConnectionConstraint(new mxPoint(0.9, 0.5), false), 6747 new mxConnectionConstraint(new mxPoint(1, 0.75), true), 6748 new mxConnectionConstraint(new mxPoint(0.25, 1), true), 6749 new mxConnectionConstraint(new mxPoint(0.5, 1), true), 6750 new mxConnectionConstraint(new mxPoint(0.75, 1), true)]; 6751 SwitchShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0), false), 6752 new mxConnectionConstraint(new mxPoint(0.5, 0.25), false), 6753 new mxConnectionConstraint(new mxPoint(1, 0), false), 6754 new mxConnectionConstraint(new mxPoint(0.25, 0.5), false), 6755 new mxConnectionConstraint(new mxPoint(0.75, 0.5), false), 6756 new mxConnectionConstraint(new mxPoint(0, 1), false), 6757 new mxConnectionConstraint(new mxPoint(0.5, 0.75), false), 6758 new mxConnectionConstraint(new mxPoint(1, 1), false)]; 6759 TapeShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0.35), false), 6760 new mxConnectionConstraint(new mxPoint(0, 0.5), false), 6761 new mxConnectionConstraint(new mxPoint(0, 0.65), false), 6762 new mxConnectionConstraint(new mxPoint(1, 0.35), false), 6763 new mxConnectionConstraint(new mxPoint(1, 0.5), false), 6764 new mxConnectionConstraint(new mxPoint(1, 0.65), false), 6765 new mxConnectionConstraint(new mxPoint(0.25, 1), false), 6766 new mxConnectionConstraint(new mxPoint(0.75, 0), false)]; 6767 StepShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.25, 0), true), 6768 new mxConnectionConstraint(new mxPoint(0.5, 0), true), 6769 new mxConnectionConstraint(new mxPoint(0.75, 0), true), 6770 new mxConnectionConstraint(new mxPoint(0.25, 1), true), 6771 new mxConnectionConstraint(new mxPoint(0.5, 1), true), 6772 new mxConnectionConstraint(new mxPoint(0.75, 1), true), 6773 new mxConnectionConstraint(new mxPoint(0, 0.25), true), 6774 new mxConnectionConstraint(new mxPoint(0, 0.5), true), 6775 new mxConnectionConstraint(new mxPoint(0, 0.75), true), 6776 new mxConnectionConstraint(new mxPoint(1, 0.25), true), 6777 new mxConnectionConstraint(new mxPoint(1, 0.5), true), 6778 new mxConnectionConstraint(new mxPoint(1, 0.75), true)]; 6779 mxLine.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0.5), false), 6780 new mxConnectionConstraint(new mxPoint(0.25, 0.5), false), 6781 new mxConnectionConstraint(new mxPoint(0.75, 0.5), false), 6782 new mxConnectionConstraint(new mxPoint(1, 0.5), false)]; 6783 LollipopShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.5, 0), false), 6784 new mxConnectionConstraint(new mxPoint(0.5, 1), false)]; 6785 mxDoubleEllipse.prototype.constraints = mxEllipse.prototype.constraints; 6786 mxRhombus.prototype.constraints = mxEllipse.prototype.constraints; 6787 mxTriangle.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0.25), true), 6788 new mxConnectionConstraint(new mxPoint(0, 0.5), true), 6789 new mxConnectionConstraint(new mxPoint(0, 0.75), true), 6790 new mxConnectionConstraint(new mxPoint(0.5, 0), true), 6791 new mxConnectionConstraint(new mxPoint(0.5, 1), true), 6792 new mxConnectionConstraint(new mxPoint(1, 0.5), true)]; 6793 mxHexagon.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.375, 0), true), 6794 new mxConnectionConstraint(new mxPoint(0.5, 0), true), 6795 new mxConnectionConstraint(new mxPoint(0.625, 0), true), 6796 new mxConnectionConstraint(new mxPoint(0, 0.25), true), 6797 new mxConnectionConstraint(new mxPoint(0, 0.5), true), 6798 new mxConnectionConstraint(new mxPoint(0, 0.75), true), 6799 new mxConnectionConstraint(new mxPoint(1, 0.25), true), 6800 new mxConnectionConstraint(new mxPoint(1, 0.5), true), 6801 new mxConnectionConstraint(new mxPoint(1, 0.75), true), 6802 new mxConnectionConstraint(new mxPoint(0.375, 1), true), 6803 new mxConnectionConstraint(new mxPoint(0.5, 1), true), 6804 new mxConnectionConstraint(new mxPoint(0.625, 1), true)]; 6805 mxCloud.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.25, 0.25), false), 6806 new mxConnectionConstraint(new mxPoint(0.4, 0.1), false), 6807 new mxConnectionConstraint(new mxPoint(0.16, 0.55), false), 6808 new mxConnectionConstraint(new mxPoint(0.07, 0.4), false), 6809 new mxConnectionConstraint(new mxPoint(0.31, 0.8), false), 6810 new mxConnectionConstraint(new mxPoint(0.13, 0.77), false), 6811 new mxConnectionConstraint(new mxPoint(0.8, 0.8), false), 6812 new mxConnectionConstraint(new mxPoint(0.55, 0.95), false), 6813 new mxConnectionConstraint(new mxPoint(0.875, 0.5), false), 6814 new mxConnectionConstraint(new mxPoint(0.96, 0.7), false), 6815 new mxConnectionConstraint(new mxPoint(0.625, 0.2), false), 6816 new mxConnectionConstraint(new mxPoint(0.88, 0.25), false)]; 6817 ParallelogramShape.prototype.constraints = mxRectangleShape.prototype.constraints; 6818 TrapezoidShape.prototype.constraints = mxRectangleShape.prototype.constraints; 6819 DocumentShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.25, 0), true), 6820 new mxConnectionConstraint(new mxPoint(0.5, 0), true), 6821 new mxConnectionConstraint(new mxPoint(0.75, 0), true), 6822 new mxConnectionConstraint(new mxPoint(0, 0.25), true), 6823 new mxConnectionConstraint(new mxPoint(0, 0.5), true), 6824 new mxConnectionConstraint(new mxPoint(0, 0.75), true), 6825 new mxConnectionConstraint(new mxPoint(1, 0.25), true), 6826 new mxConnectionConstraint(new mxPoint(1, 0.5), true), 6827 new mxConnectionConstraint(new mxPoint(1, 0.75), true)]; 6828 mxArrow.prototype.constraints = null; 6829 6830 TeeShape.prototype.getConstraints = function(style, w, h) 6831 { 6832 var constr = []; 6833 var dx = Math.max(0, Math.min(w, parseFloat(mxUtils.getValue(this.style, 'dx', this.dx)))); 6834 var dy = Math.max(0, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'dy', this.dy)))); 6835 var w2 = Math.abs(w - dx) / 2; 6836 6837 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false)); 6838 constr.push(new mxConnectionConstraint(new mxPoint(0.5, 0), false)); 6839 constr.push(new mxConnectionConstraint(new mxPoint(1, 0), false)); 6840 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w, dy * 0.5)); 6841 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w, dy)); 6842 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w * 0.75 + dx * 0.25, dy)); 6843 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, (w + dx) * 0.5, dy)); 6844 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, (w + dx) * 0.5, (h + dy) * 0.5)); 6845 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, (w + dx) * 0.5, h)); 6846 constr.push(new mxConnectionConstraint(new mxPoint(0.5, 1), false)); 6847 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, (w - dx) * 0.5, h)); 6848 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, (w - dx) * 0.5, (h + dy) * 0.5)); 6849 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, (w - dx) * 0.5, dy)); 6850 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w * 0.25 - dx * 0.25, dy)); 6851 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, 0, dy)); 6852 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, 0, dy * 0.5)); 6853 6854 return (constr); 6855 }; 6856 6857 CornerShape.prototype.getConstraints = function(style, w, h) 6858 { 6859 var constr = []; 6860 var dx = Math.max(0, Math.min(w, parseFloat(mxUtils.getValue(this.style, 'dx', this.dx)))); 6861 var dy = Math.max(0, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'dy', this.dy)))); 6862 6863 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false)); 6864 constr.push(new mxConnectionConstraint(new mxPoint(0.5, 0), false)); 6865 constr.push(new mxConnectionConstraint(new mxPoint(1, 0), false)); 6866 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w, dy * 0.5)); 6867 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w, dy)); 6868 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, (w + dx) * 0.5, dy)); 6869 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, dx, dy)); 6870 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, dx, (h + dy) * 0.5)); 6871 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, dx, h)); 6872 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, dx * 0.5, h)); 6873 constr.push(new mxConnectionConstraint(new mxPoint(0, 0.5), false)); 6874 constr.push(new mxConnectionConstraint(new mxPoint(0, 1), false)); 6875 6876 return (constr); 6877 }; 6878 6879 CrossbarShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0), false), 6880 new mxConnectionConstraint(new mxPoint(0, 0.5), false), 6881 new mxConnectionConstraint(new mxPoint(0, 1), false), 6882 new mxConnectionConstraint(new mxPoint(0.25, 0.5), false), 6883 new mxConnectionConstraint(new mxPoint(0.5, 0.5), false), 6884 new mxConnectionConstraint(new mxPoint(0.75, 0.5), false), 6885 new mxConnectionConstraint(new mxPoint(1, 0), false), 6886 new mxConnectionConstraint(new mxPoint(1, 0.5), false), 6887 new mxConnectionConstraint(new mxPoint(1, 1), false)]; 6888 6889 SingleArrowShape.prototype.getConstraints = function(style, w, h) 6890 { 6891 var constr = []; 6892 var aw = h * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'arrowWidth', this.arrowWidth)))); 6893 var as = w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'arrowSize', this.arrowSize)))); 6894 var at = (h - aw) / 2; 6895 var ab = at + aw; 6896 6897 constr.push(new mxConnectionConstraint(new mxPoint(0, 0.5), false)); 6898 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, 0, at)); 6899 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, (w - as) * 0.5, at)); 6900 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w - as, 0)); 6901 constr.push(new mxConnectionConstraint(new mxPoint(1, 0.5), false)); 6902 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w - as, h)); 6903 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, (w - as) * 0.5, h - at)); 6904 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, 0, h - at)); 6905 6906 return (constr); 6907 }; 6908 6909 DoubleArrowShape.prototype.getConstraints = function(style, w, h) 6910 { 6911 var constr = []; 6912 var aw = h * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'arrowWidth', SingleArrowShape.prototype.arrowWidth)))); 6913 var as = w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'arrowSize', SingleArrowShape.prototype.arrowSize)))); 6914 var at = (h - aw) / 2; 6915 var ab = at + aw; 6916 6917 constr.push(new mxConnectionConstraint(new mxPoint(0, 0.5), false)); 6918 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, as, 0)); 6919 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w * 0.5, at)); 6920 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w - as, 0)); 6921 constr.push(new mxConnectionConstraint(new mxPoint(1, 0.5), false)); 6922 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w - as, h)); 6923 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w * 0.5, h - at)); 6924 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, as, h)); 6925 6926 return (constr); 6927 }; 6928 6929 CrossShape.prototype.getConstraints = function(style, w, h) 6930 { 6931 var constr = []; 6932 var m = Math.min(h, w); 6933 var size = Math.max(0, Math.min(m, m * parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); 6934 var t = (h - size) / 2; 6935 var b = t + size; 6936 var l = (w - size) / 2; 6937 var r = l + size; 6938 6939 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, l, t * 0.5)); 6940 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, l, 0)); 6941 constr.push(new mxConnectionConstraint(new mxPoint(0.5, 0), false)); 6942 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, r, 0)); 6943 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, r, t * 0.5)); 6944 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, r, t)); 6945 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, l, h - t * 0.5)); 6946 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, l, h)); 6947 constr.push(new mxConnectionConstraint(new mxPoint(0.5, 1), false)); 6948 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, r, h)); 6949 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, r, h - t * 0.5)); 6950 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, r, b)); 6951 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, (w + r) * 0.5, t)); 6952 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w, t)); 6953 constr.push(new mxConnectionConstraint(new mxPoint(1, 0.5), false)); 6954 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, w, b)); 6955 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, (w + r) * 0.5, b)); 6956 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, l, b)); 6957 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, l * 0.5, t)); 6958 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, 0, t)); 6959 constr.push(new mxConnectionConstraint(new mxPoint(0, 0.5), false)); 6960 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, 0, b)); 6961 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, l * 0.5, b)); 6962 constr.push(new mxConnectionConstraint(new mxPoint(0, 0), false, null, l, t)); 6963 6964 return (constr); 6965 }; 6966 6967 UmlLifeline.prototype.constraints = null; 6968 OrShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0.25), false), 6969 new mxConnectionConstraint(new mxPoint(0, 0.5), false), 6970 new mxConnectionConstraint(new mxPoint(0, 0.75), false), 6971 new mxConnectionConstraint(new mxPoint(1, 0.5), false), 6972 new mxConnectionConstraint(new mxPoint(0.7, 0.1), false), 6973 new mxConnectionConstraint(new mxPoint(0.7, 0.9), false)]; 6974 XorShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.175, 0.25), false), 6975 new mxConnectionConstraint(new mxPoint(0.25, 0.5), false), 6976 new mxConnectionConstraint(new mxPoint(0.175, 0.75), false), 6977 new mxConnectionConstraint(new mxPoint(1, 0.5), false), 6978 new mxConnectionConstraint(new mxPoint(0.7, 0.1), false), 6979 new mxConnectionConstraint(new mxPoint(0.7, 0.9), false)]; 6980 RequiredInterfaceShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0.5), false), 6981 new mxConnectionConstraint(new mxPoint(1, 0.5), false)]; 6982 ProvidedRequiredInterfaceShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0.5), false), 6983 new mxConnectionConstraint(new mxPoint(1, 0.5), false)]; 6984})(); 6985