all files / diagram/interaction/ scroller.js

93.8% Statements 439/468
92.03% Branches 277/301
100% Functions 27/27
93.8% Lines 439/468
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692   1302× 1302× 1302× 1302× 1302× 1302× 1302× 1302× 1302× 1302× 1302× 1302× 1302× 1302× 1302× 1302× 1302× 1302× 1302×     21655×     1313× 1313×           158086×     270× 270×           21675×     1313× 1313×           39550×     446× 446× 197× 197×   446×           39503×     450× 450× 214× 214×   450×         4786× 4786× 4786× 703×     4083×   4786×   4544× 4544× 4544× 4544× 4544× 4544× 4544× 4544× 4544× 4544×     4543×   4544×         242× 242× 242× 242× 242× 242× 242× 242× 242× 242× 242× 242× 242× 50× 30× 30×         30×   50× 50×                     50× 17×     242× 242× 242× 54× 38× 38×         38×   54× 54×                     54× 15×     242×       242×   102× 102× 1206× 1206× 27748× 1067× 1067×     1206× 139×     102×   51× 51× 51× 51× 51× 51× 603× 603×     600× 597×     51× 51× 51× 603× 603×     600× 597×     51× 603× 16444× 603× 603×       51× 51×   51× 51× 51×   5074× 5074× 5074× 5074× 5074× 5074× 5074× 5074× 5074× 5074× 5074× 5074× 3942×   5074× 3752×   5074× 5074× 5074× 5074× 5074× 5074× 5074× 137×   5074× 4822×       2010× 51×         51× 51×   2010× 2010× 125× 125× 125×             2812×                     5074× 5074×   1313× 1313×   22160× 22160× 22160× 22160× 889× 889× 889× 889× 889× 177× 177× 148× 148×   177× 148× 148×   177× 43× 43×   177× 11× 11×     889×     21271× 21271×   22160× 10150× 10150× 10150× 10150× 10150×   22160×   107× 107× 107× 107× 107× 107× 107× 107× 107× 107× 107× 107× 107× 107× 107× 107× 175× 175× 107×       107×   175× 68× 68× 68× 68× 68× 68× 68×   175× 107×       107×     107× 147× 147× 107×       107×   147× 40× 40× 40× 40× 40× 40× 40×   147× 107×       107×     107×   273× 273× 273× 273× 273×       273× 273×   270× 270× 270× 270× 270× 270× 270× 270× 270× 270× 185×   270× 270×     213×         213× 213×   270× 270×   270×   270× 270× 270×                 24× 24× 24× 24× 24× 24× 24× 24× 24× 24× 24× 24× 24× 24× 24× 24× 24×   23× 23× 20×   23× 23×                   23×                   23× 23× 23×   10× 10×   23× 23× 23× 23×       17× 17× 17× 17× 17× 17× 17×   23×                                 185× 102×     185× 83× 83×   83× 83× 83× 83× 83× 83× 72× 72×   83×   83× 83×             83× 83×               83× 83×   185×        
define(["require", "exports", "../primitives/rect", "../enum/enum", "../primitives/matrix", "../ruler/ruler", "./../utility/constraints-util"], function (require, exports, rect_1, enum_1, matrix_1, ruler_1, constraints_util_1) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    var DiagramScroller = (function () {
        function DiagramScroller(diagram) {
            this.transform = { tx: 0, ty: 0, scale: 1 };
            this.oldCollectionObjects = [];
            this.removeCollection = [];
            this.vPortWidth = 0;
            this.vPortHeight = 0;
            this.currentZoomFActor = 1;
            this.hOffset = 0;
            this.vOffset = 0;
            this.scrolled = false;
            this.hScrollSize = 0;
            this.vScrollSize = 0;
            this.diagram = diagram;
            this.objects = [];
            this.transform = diagram.scroller ? diagram.scroller.transform : { tx: 0, ty: 0, scale: 1 };
            this.vPortWidth = diagram.scrollSettings.viewPortWidth;
            this.vPortHeight = diagram.scrollSettings.viewPortHeight;
            this.currentZoomFActor = diagram.scrollSettings.currentZoom;
            this.hOffset = diagram.scrollSettings.horizontalOffset;
            this.vOffset = diagram.scrollSettings.verticalOffset;
        }
        Object.defineProperty(DiagramScroller.prototype, "viewPortHeight", {
            get: function () {
                return this.vPortHeight;
            },
            set: function (offset) {
                this.vPortHeight = offset;
                this.diagram.scrollSettings.viewPortHeight = offset;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DiagramScroller.prototype, "currentZoom", {
            get: function () {
                return this.currentZoomFActor;
            },
            set: function (offset) {
                this.currentZoomFActor = offset;
                this.diagram.scrollSettings.currentZoom = offset;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DiagramScroller.prototype, "viewPortWidth", {
            get: function () {
                return this.vPortWidth;
            },
            set: function (offset) {
                this.vPortWidth = offset;
                this.diagram.scrollSettings.viewPortWidth = offset;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DiagramScroller.prototype, "horizontalOffset", {
            get: function () {
                return this.hOffset;
            },
            set: function (offset) {
                this.hOffset = offset;
                if (Math.abs(this.hOffset - this.diagram.scrollSettings.horizontalOffset) > 1) {
                    this.diagram.realActions = this.diagram.realActions | enum_1.RealAction.hScrollbarMoved;
                    this.scrolled = true;
                }
                this.diagram.scrollSettings.horizontalOffset = offset;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DiagramScroller.prototype, "verticalOffset", {
            get: function () {
                return this.vOffset;
            },
            set: function (offset) {
                this.vOffset = offset;
                if (Math.abs(this.vOffset - this.diagram.scrollSettings.verticalOffset) > 1) {
                    this.diagram.realActions = this.diagram.realActions | enum_1.RealAction.vScrollbarMoved;
                    this.scrolled = true;
                }
                this.diagram.scrollSettings.verticalOffset = offset;
            },
            enumerable: true,
            configurable: true
        });
        DiagramScroller.prototype.getBounds = function () {
            var pageBounds;
            var postion = this.diagram.spatialSearch.getPageBounds(0, 0);
            if ((postion.x < 0 || postion.y < 0) && !this.diagram.pageSettings.multiplePage) {
                pageBounds = this.getPageBounds(undefined, undefined, true, true);
            }
            else {
                pageBounds = this.getPageBounds(undefined, undefined, true);
            }
            return pageBounds;
        };
        DiagramScroller.prototype.updateScrollOffsets = function (hOffset, vOffset) {
            var offsetX = 0;
            var offsetY = 0;
            var pageBounds = this.getBounds();
            pageBounds.x *= this.currentZoom;
            pageBounds.y *= this.currentZoom;
            pageBounds.width *= this.currentZoom;
            pageBounds.height *= this.currentZoom;
            offsetX = Math.max(0, hOffset - pageBounds.left);
            offsetY = Math.max(0, vOffset - pageBounds.top);
            if (hOffset !== undefined && vOffset !== undefined) {
                this.horizontalOffset = offsetX;
                this.verticalOffset = offsetY;
                this.diagram.setOffset(offsetX, offsetY);
            }
            else {
                this.diagram.setOffset(-this.horizontalOffset - pageBounds.x, -this.verticalOffset - pageBounds.y);
            }
            this.transform = {
                tx: Math.max(this.horizontalOffset, -pageBounds.left) / this.currentZoom, ty: Math.max(this.verticalOffset, -pageBounds.top) / this.currentZoom,
                scale: this.currentZoom
            };
        };
        DiagramScroller.prototype.setScrollOffset = function (hOffset, vOffset) {
            this.scrolled = false;
            var pageBounds = this.getBounds();
            pageBounds.x *= this.currentZoom;
            pageBounds.y *= this.currentZoom;
            pageBounds.width *= this.currentZoom;
            pageBounds.height *= this.currentZoom;
            var x = -pageBounds.left;
            var y = -pageBounds.top;
            var set = false;
            var viewWidth = this.viewPortWidth * this.currentZoom;
            var viewHeight = this.viewPortHeight * this.currentZoom;
            var newX = x - hOffset;
            if (newX !== this.horizontalOffset) {
                if (x < this.horizontalOffset) {
                    Eif (this.horizontalOffset > newX) {
                        this.horizontalOffset -= hOffset;
                    }
                    else {
                        this.horizontalOffset = newX;
                    }
                    set = true;
                }
                var right = Math.max(pageBounds.right + this.vScrollSize, viewWidth);
                if (!set && right < -newX + this.viewPortWidth) {
                    var actualRight = -newX + viewWidth - this.vScrollSize;
                    var currentRight = -this.horizontalOffset + viewWidth - this.vScrollSize;
                    Eif (actualRight < currentRight) {
                        this.horizontalOffset = newX;
                    }
                    else {
                        if (actualRight - pageBounds.right > actualRight - currentRight) {
                            this.horizontalOffset = newX;
                        }
                        else {
                            this.horizontalOffset = -(pageBounds.right + this.vScrollSize - viewWidth);
                        }
                    }
                    set = true;
                }
                if (!set) {
                    this.horizontalOffset = x - hOffset;
                }
            }
            set = false;
            var newY = y - vOffset;
            if (newY !== this.verticalOffset) {
                if (y < this.verticalOffset) {
                    Eif (this.verticalOffset > newY) {
                        this.verticalOffset -= vOffset;
                    }
                    else {
                        this.verticalOffset = newY;
                    }
                    set = true;
                }
                var bottom = Math.max(pageBounds.bottom + this.hScrollSize, viewHeight);
                if (!set && bottom < -newY + viewHeight) {
                    var actualBottom = -newY + viewHeight - this.hScrollSize;
                    var currentBottom = -this.verticalOffset + viewHeight - this.hScrollSize;
                    Eif (actualBottom < currentBottom) {
                        this.verticalOffset = newY;
                    }
                    else {
                        if (actualBottom - pageBounds.bottom > actualBottom - currentBottom) {
                            this.verticalOffset = newY;
                        }
                        else {
                            this.verticalOffset = -(pageBounds.bottom + this.hScrollSize - viewHeight);
                        }
                    }
                    set = true;
                }
                if (!set) {
                    this.verticalOffset = y - vOffset;
                }
            }
            this.transform = {
                tx: Math.max(this.horizontalOffset, -pageBounds.left) / this.currentZoom, ty: Math.max(this.verticalOffset, -pageBounds.top) / this.currentZoom,
                scale: this.currentZoom
            };
            this.setSize();
        };
        DiagramScroller.prototype.getObjects = function (coll1, coll2) {
            var objects = [];
            for (var i = 0; i < coll1.length; i++) {
                var isExist = false;
                for (var j = 0; j < coll2.length; j++) {
                    if (coll1[parseInt(i.toString(), 10)] === coll2[parseInt(j.toString(), 10)]) {
                        isExist = true;
                        break;
                    }
                }
                if (!isExist) {
                    objects.push(coll1[parseInt(i.toString(), 10)]);
                }
            }
            return objects;
        };
        DiagramScroller.prototype.virtualizeElements = function () {
            var viewWidth = this.viewPortWidth / this.currentZoom;
            var viewHeight = this.viewPortHeight / this.currentZoom;
            var oObjects = this.diagram.spatialSearch.findObjects(new rect_1.Rect(-this.horizontalOffset / this.currentZoom, -this.verticalOffset / this.currentZoom, viewWidth, viewHeight));
            var oObjectsID = [];
            var renderOrder = [];
            for (var j = 0; j < oObjects.length; j++) {
                var bpmnShape = oObjects[parseInt(j.toString(), 10)].shape;
                if (bpmnShape.type === 'Bpmn' && bpmnShape && bpmnShape.activity && bpmnShape.activity.subProcess && bpmnShape.activity.subProcess.processes && bpmnShape.activity.subProcess.processes.length > 0) {
                    for (var k = 0; k < bpmnShape.activity.subProcess.processes.length; k++) {
                        renderOrder.push(bpmnShape.activity.subProcess.processes[parseInt(k.toString(), 10)]);
                    }
                    renderOrder.push(oObjects[parseInt(j.toString(), 10)].id);
                }
                else if (oObjects[parseInt(j.toString(), 10)].processId === '' || oObjects[parseInt(j.toString(), 10)].processId === undefined) {
                    renderOrder.push(oObjects[parseInt(j.toString(), 10)].id);
                }
            }
            oObjectsID = renderOrder;
            var zindexOrder = [];
            for (var j = 0; j < oObjects.length; j++) {
                var items = oObjects[parseInt(j.toString(), 10)].shape;
                if (items.type === 'Bpmn' && items && items.activity && items.activity.subProcess && items.activity.subProcess.processes && items.activity.subProcess.processes.length > 0) {
                    zindexOrder.push(oObjects[parseInt(j.toString(), 10)].id);
                    for (var t = 0; t < items.activity.subProcess.processes.length; t++) {
                        zindexOrder.push(items.activity.subProcess.processes[parseInt(t.toString(), 10)]);
                    }
                }
                else if (oObjects[parseInt(j.toString(), 10)].processId === '' || oObjects[parseInt(j.toString(), 10)].processId === undefined) {
                    zindexOrder.push(oObjects[parseInt(j.toString(), 10)].id);
                }
            }
            for (var j = 0; j < oObjects.length; j++) {
                for (var k = 0; k < zindexOrder.length; k++) {
                    if (oObjects[parseInt(j.toString(), 10)].id === zindexOrder[parseInt(k.toString(), 10)]) {
                        oObjects[parseInt(j.toString(), 10)].zIndex = k;
                        break;
                    }
                }
            }
            var newObjects = this.getObjects(oObjectsID, this.oldCollectionObjects);
            if (this.oldCollectionObjects.length === 0) {
                this.oldCollectionObjects = oObjectsID;
            }
            var removeObjects = this.getObjects(this.oldCollectionObjects, oObjectsID);
            this.diagram.updateVirtualObjects(newObjects, false, removeObjects);
            this.oldCollectionObjects = oObjectsID;
        };
        DiagramScroller.prototype.setSize = function (newOffset) {
            var pageBounds = this.getPageBounds(undefined, undefined, true);
            pageBounds.x *= this.currentZoom;
            pageBounds.y *= this.currentZoom;
            pageBounds.width *= this.currentZoom;
            pageBounds.height *= this.currentZoom;
            var x = Math.min(pageBounds.x, -this.horizontalOffset);
            var y = Math.min(pageBounds.y, -this.verticalOffset);
            var difX = -this.horizontalOffset + this.viewPortWidth - pageBounds.right;
            var difY = -this.verticalOffset + this.viewPortHeight - pageBounds.bottom;
            var hScrollSize = this.scrollerWidth;
            var vScrollSize = this.scrollerWidth;
            if (-this.verticalOffset <= pageBounds.y && -this.verticalOffset + this.viewPortHeight >= pageBounds.bottom) {
                vScrollSize = 0;
            }
            if (-this.horizontalOffset <= pageBounds.x && -this.horizontalOffset + this.viewPortWidth >= pageBounds.right) {
                hScrollSize = 0;
            }
            this.hScrollSize = hScrollSize;
            this.vScrollSize = vScrollSize;
            var oldWidth = this.diagramWidth;
            var oldHeight = this.diagramHeight;
            this.diagramWidth = Math.max(pageBounds.right, -this.horizontalOffset + this.viewPortWidth - vScrollSize) - x;
            this.diagramHeight = Math.max(pageBounds.bottom, -this.verticalOffset + this.viewPortHeight - hScrollSize) - y;
            if ((oldWidth !== this.diagramWidth || oldHeight !== this.diagramHeight) && this.diagram.scrollSettings.scrollLimit !== 'Diagram') {
                this.diagram.setSize(this.diagramWidth, this.diagramHeight);
            }
            if (this.diagram.scrollSettings.scrollLimit === 'Diagram') {
                if ((oldWidth !== this.diagramWidth || oldHeight !== this.diagramHeight || this.currentZoom !== 1)
                    && ((!this.diagram.diagramActions || !newOffset) || (this.diagram.diagramActions && newOffset &&
                        ((this.verticalOffset !== 0 || this.verticalOffset === newOffset.y) &&
                            (this.horizontalOffset !== 0 || this.horizontalOffset === newOffset.x))))) {
                    if ((this.diagram.scrollActions & enum_1.ScrollActions.Interaction) && newOffset) {
                        this.transform = {
                            tx: Math.max(newOffset.x, -(pageBounds.left / this.currentZoom)) / this.currentZoom,
                            ty: Math.max(newOffset.y, -(pageBounds.top / this.currentZoom)) / this.currentZoom,
                            scale: this.currentZoom
                        };
                        this.horizontalOffset = newOffset.x;
                        this.verticalOffset = newOffset.y;
                    }
                    this.diagram.setSize(this.diagramWidth, this.diagramHeight);
                    if ((!(this.diagram.scrollActions & enum_1.ScrollActions.PropertyChange)) && newOffset) {
                        this.horizontalOffset = newOffset.x;
                        this.verticalOffset = newOffset.y;
                        this.transform = {
                            tx: Math.max(newOffset.x, -pageBounds.left) / this.currentZoom,
                            ty: Math.max(newOffset.y, -pageBounds.top) / this.currentZoom,
                            scale: this.currentZoom
                        };
                    }
                }
                else if (newOffset && oldWidth === this.diagramWidth && oldHeight === this.diagramHeight &&
                    ((this.diagram.diagramCanvas.scrollHeight > this.viewPortHeight &&
                        newOffset.y < 0 && this.horizontalOffset === newOffset.x && this.verticalOffset === 0) ||
                        (this.diagram.diagramCanvas.scrollWidth > this.viewPortWidth &&
                            newOffset.x < 0 && this.verticalOffset === newOffset.y && this.horizontalOffset === 0))) {
                    this.verticalOffset = newOffset.y;
                    this.horizontalOffset = newOffset.x;
                    this.transform = {
                        tx: Math.max(newOffset.x, -pageBounds.left) / this.currentZoom,
                        ty: Math.max(newOffset.y, -pageBounds.top) / this.currentZoom,
                        scale: this.currentZoom
                    };
                }
            }
            this.diagram.transformLayers();
            this.diagram.element.style.overflow = 'hidden';
        };
        DiagramScroller.prototype.setViewPortSize = function (width, height) {
            this.viewPortWidth = width;
            this.viewPortHeight = height;
        };
        DiagramScroller.prototype.getPageBounds = function (boundingRect, region, hasPadding, isnegativeRegion) {
            var rect = new rect_1.Rect();
            var temp = 0;
            var pageBounds;
            if (region !== 'Content' && !isnegativeRegion && this.diagram.pageSettings.width !== null && this.diagram.pageSettings.height !== null) {
                var width = this.diagram.pageSettings.width;
                var height = this.diagram.pageSettings.height;
                var negwidth = 0;
                var negheight = 0;
                if (this.diagram.pageSettings.multiplePage) {
                    rect = this.diagram.spatialSearch.getPageBounds(0, 0);
                    if (rect.right > width) {
                        var x = Math.ceil(rect.right / width);
                        width = width * x;
                    }
                    if (rect.bottom > height) {
                        var x = Math.ceil(rect.bottom / height);
                        height = height * x;
                    }
                    if (rect.left < 0 && Math.abs(rect.left) > negwidth) {
                        var x = Math.ceil(Math.abs(rect.left) / this.diagram.pageSettings.width);
                        negwidth = this.diagram.pageSettings.width * x;
                    }
                    if (rect.top < 0 && Math.abs(rect.top) > negheight) {
                        var x = Math.ceil(Math.abs(rect.top) / this.diagram.pageSettings.height);
                        negheight = this.diagram.pageSettings.height * x;
                    }
                }
                pageBounds = new rect_1.Rect((-negwidth), (-negheight), width + negwidth, height + negheight);
            }
            else {
                var origin_1 = boundingRect ? undefined : 0;
                pageBounds = this.diagram.spatialSearch.getPageBounds(origin_1, origin_1);
            }
            if (hasPadding) {
                var scrollpadding = this.diagram.scrollSettings.padding;
                pageBounds.x -= scrollpadding.left;
                pageBounds.y -= scrollpadding.top;
                pageBounds.width += (scrollpadding.left + scrollpadding.right);
                pageBounds.height += (scrollpadding.top + scrollpadding.bottom);
            }
            return pageBounds;
        };
        DiagramScroller.prototype.getPageBreak = function (pageBounds) {
            var i = 0;
            var j = 0;
            var v = -1;
            var collection = [];
            var x1 = 0;
            var x2 = 0;
            var y1 = 0;
            var y2 = 0;
            var left = this.diagram.pageSettings.margin.left;
            var right = this.diagram.pageSettings.margin.right;
            var top = this.diagram.pageSettings.margin.top;
            var bottom = this.diagram.pageSettings.margin.bottom;
            var widthCount = 1;
            var heightCount = 1;
            var segment = { x1: x1, y1: y1, x2: x2, y2: y2 };
            while (pageBounds.width > i) {
                i = i + (this.diagram.pageSettings.width ? this.diagram.pageSettings.width : pageBounds.width);
                if (i === this.diagram.pageSettings.width) {
                    segment = {
                        x1: pageBounds.left + left, y1: pageBounds.top + top,
                        x2: pageBounds.left + left, y2: pageBounds.bottom - bottom
                    };
                    collection[++v] = segment;
                }
                if (i < pageBounds.width) {
                    x1 = pageBounds.topLeft.x + this.diagram.pageSettings.width * widthCount;
                    y1 = pageBounds.topLeft.y + top;
                    x2 = pageBounds.bottomLeft.x + this.diagram.pageSettings.width * widthCount;
                    y2 = pageBounds.bottomLeft.y - bottom;
                    segment = { x1: x1, y1: y1, x2: x2, y2: y2 };
                    collection[++v] = segment;
                    widthCount++;
                }
                if (pageBounds.width === i) {
                    segment = {
                        x1: pageBounds.right - right, y1: pageBounds.top + top,
                        x2: pageBounds.right - right, y2: pageBounds.bottom - bottom
                    };
                    collection[++v] = segment;
                }
            }
            while (pageBounds.height > j) {
                j = j + (this.diagram.pageSettings.height ? this.diagram.pageSettings.height : pageBounds.height);
                if (j === this.diagram.pageSettings.height) {
                    segment = {
                        x1: pageBounds.left + left, y1: pageBounds.top + top,
                        x2: pageBounds.right - right, y2: pageBounds.top + top
                    };
                    collection[++v] = segment;
                }
                if (j < pageBounds.height) {
                    x1 = pageBounds.topLeft.x + left;
                    y1 = pageBounds.topLeft.y + this.diagram.pageSettings.height * heightCount;
                    x2 = pageBounds.topRight.x - right;
                    y2 = pageBounds.topRight.y + this.diagram.pageSettings.height * heightCount;
                    segment = { x1: x1, y1: y1, x2: x2, y2: y2 };
                    collection[++v] = segment;
                    heightCount++;
                }
                if (pageBounds.height === j) {
                    segment = {
                        x1: pageBounds.left + left, y1: pageBounds.bottom - bottom,
                        x2: pageBounds.right - right, y2: pageBounds.bottom - bottom
                    };
                    collection[++v] = segment;
                }
            }
            return collection;
        };
        DiagramScroller.prototype.zoom = function (factor, deltaX, deltaY, focusPoint, isInteractiveZoomPan, isBringIntoView, isTrackpadScroll, canZoomOut) {
            Eif (constraints_util_1.canZoom(this.diagram) && factor !== 1 || (constraints_util_1.canPan(this.diagram) && factor === 1)) {
                var matrix = matrix_1.identityMatrix();
                matrix_1.scaleMatrix(matrix, this.currentZoom, this.currentZoom);
                matrix_1.translateMatrix(matrix, this.horizontalOffset, this.verticalOffset);
                focusPoint = focusPoint || {
                    x: (this.viewPortWidth / 2 - this.horizontalOffset) / this.currentZoom,
                    y: (this.viewPortHeight / 2 - this.verticalOffset) / this.currentZoom
                };
                focusPoint = matrix_1.transformPointByMatrix(matrix, focusPoint);
                if ((this.currentZoom * factor) <= this.diagram.scrollSettings.maxZoom &&
                    ((this.currentZoom * factor) >= this.diagram.scrollSettings.minZoom || (canZoomOut || factor >= 1))) {
                    this.currentZoom *= factor;
                    var pageBounds = this.getPageBounds(undefined, undefined, true);
                    pageBounds.x *= this.currentZoom;
                    pageBounds.y *= this.currentZoom;
                    var targetMatrix = matrix_1.identityMatrix();
                    matrix_1.scaleMatrix(targetMatrix, factor, factor, focusPoint.x, focusPoint.y);
                    matrix_1.translateMatrix(targetMatrix, deltaX || 0, deltaY || 0);
                    matrix_1.multiplyMatrix(matrix, targetMatrix);
                    var newOffset = matrix_1.transformPointByMatrix(matrix, { x: 0, y: 0 });
                    if (factor === 1) {
                        newOffset = this.applyScrollLimit(newOffset.x, newOffset.y, isInteractiveZoomPan, isBringIntoView, isTrackpadScroll);
                    }
                    isTrackpadScroll = (-(pageBounds.y) >= newOffset.y && -(pageBounds.x) >= newOffset.x && isTrackpadScroll);
                    if ((this.diagram.scrollActions & enum_1.ScrollActions.PropertyChange ||
                        !(this.diagram.scrollActions & enum_1.ScrollActions.Interaction)) ||
                        this.diagram.scrollSettings.scrollLimit !== 'Diagram' || isTrackpadScroll) {
                        this.transform = {
                            tx: Math.max(newOffset.x, -pageBounds.left) / this.currentZoom,
                            ty: Math.max(newOffset.y, -pageBounds.top) / this.currentZoom,
                            scale: this.currentZoom
                        };
                        this.horizontalOffset = newOffset.x;
                        this.verticalOffset = newOffset.y;
                    }
                    this.setSize(newOffset);
                    if (this.diagram.mode !== 'SVG' && constraints_util_1.canVitualize(this.diagram)) {
                        this.diagram.scroller.virtualizeElements();
                    }
                    if (this.diagram.mode !== 'SVG' && !constraints_util_1.canVitualize(this.diagram)) {
                        this.diagram.refreshDiagramLayer();
                    }
                    this.diagram.setOffset(-this.horizontalOffset - pageBounds.x, -this.verticalOffset - pageBounds.y);
                    ruler_1.updateRuler(this.diagram);
                    Iif (this.diagram.views && this.diagram.views.overview) {
                        var overview = this.diagram.views.overview;
                        var bounds = overview.scrollOverviewRect(overview.parent.scroller.horizontalOffset, overview.parent.scroller.verticalOffset, overview.parent.scroller.currentZoom, true);
                        overview.updateOverviewrect(-bounds.x, -bounds.y, bounds.width, bounds.height);
                        overview.updateView(overview);
                    }
                }
            }
        };
        DiagramScroller.prototype.fitToPage = function (options) {
            options = options || {};
            var mode = options.mode;
            var region = options.region;
            var margin = options.margin || {};
            var canZoomIn = options.canZoomIn;
            var customBounds = options.customBounds;
            var canZoomOut = options.canZoomOut;
            margin.bottom = margin.bottom || 25;
            margin.top = margin.top || 25;
            margin.left = margin.left || 25;
            margin.right = margin.right || 25;
            var bounds = customBounds;
            var factor;
            var deltaX = -this.horizontalOffset;
            var deltaY = -this.verticalOffset;
            region = region ? region : 'PageSettings';
            if ((region === 'PageSettings' && this.diagram.pageSettings.width && this.diagram.pageSettings.height)
                || (this.diagram.nodes.length > 0 || this.diagram.connectors.length > 0)) {
                mode = mode ? mode : 'Page';
                if (region !== 'CustomBounds') {
                    bounds = this.getPageBounds(true, region, true);
                }
                var scale = { x: 0, y: 0 };
                Iif ((margin.left + margin.right) > this.viewPortWidth) {
                    if (this.viewPortWidth <= 100) {
                        margin.left = 5;
                        margin.right = 5;
                    }
                    else {
                        margin.left = 25;
                        margin.right = 25;
                    }
                }
                Iif ((margin.top + margin.bottom) > this.viewPortHeight) {
                    if (this.viewPortHeight <= 100) {
                        margin.top = 5;
                        margin.bottom = 5;
                    }
                    else {
                        margin.top = 25;
                        margin.bottom = 25;
                    }
                }
                scale.x = (this.viewPortWidth - (margin.left + margin.right)) / (bounds.width);
                scale.y = (this.viewPortHeight - (margin.top + margin.bottom)) / (bounds.height);
                if (!canZoomIn && (((bounds.width - this.horizontalOffset) < this.viewPortWidth) &&
                    (bounds.height - this.verticalOffset) < this.viewPortHeight)) {
                    scale.x = Math.min(this.currentZoom, scale.x);
                    scale.y = Math.min(this.currentZoom, scale.y);
                }
                var zoomFactor = void 0;
                var centerX = void 0;
                var centerY = void 0;
                switch (mode) {
                    case 'Width':
                        zoomFactor = scale.x;
                        factor = zoomFactor / this.currentZoom;
                        centerX = (this.viewPortWidth - (bounds.width) * zoomFactor) / 2 - bounds.x * zoomFactor;
                        deltaX += centerX + (margin.left - margin.right) / 2 * zoomFactor;
                        deltaY -= -this.verticalOffset * factor;
                        deltaY = region !== 'CustomBounds' ? deltaY : deltaY - this.verticalOffset * factor;
                        break;
                    case 'Height':
                        zoomFactor = scale.y;
                        factor = (zoomFactor / this.currentZoom);
                        centerX = ((this.viewPortWidth - (bounds.width) * zoomFactor) / 2) - bounds.x * zoomFactor;
                        centerY = ((this.viewPortHeight - (bounds.height) * zoomFactor) / 2) - bounds.y * zoomFactor;
                        deltaX += centerX + (margin.left - margin.right) / 2 * zoomFactor;
                        deltaY += centerY + (margin.top - margin.bottom) / 2 * zoomFactor;
                        break;
                    case 'Page':
                        zoomFactor = Math.min(scale.x, scale.y);
                        factor = (zoomFactor / this.currentZoom);
                        centerX = (this.viewPortWidth - (bounds.width) * zoomFactor) / 2 - bounds.x * zoomFactor;
                        centerY = (this.viewPortHeight - (bounds.height) * zoomFactor) / 2 - bounds.y * zoomFactor;
                        deltaX += centerX + (margin.left - margin.right) / 2 * zoomFactor;
                        deltaY += centerY + (margin.top - margin.bottom) / 2 * zoomFactor;
                        break;
                }
                this.zoom(factor, deltaX, deltaY, { x: 0, y: 0 }, true, undefined, undefined, canZoomOut);
            }
            else {
                factor = 1 / this.currentZoom;
                this.zoom(factor, deltaX, deltaY, { x: 0, y: 0 }, true, undefined, undefined, canZoomOut);
            }
        };
        DiagramScroller.prototype.bringIntoView = function (rect, isBringIntoView) {
            var x = 0;
            var y = 0;
            var scale = this.currentZoom;
            var bounds = rect;
            var hoffset = -this.horizontalOffset;
            var voffset = -this.verticalOffset;
            bounds = new rect_1.Rect(bounds.x * scale, bounds.y * scale, bounds.width * scale, bounds.height * scale);
            var view = new rect_1.Rect(hoffset, voffset, this.viewPortWidth, this.viewPortHeight);
            var nodePadding = 20;
            if (!(view.containsRect(bounds))) {
                Iif (bounds.right > (-hoffset + this.viewPortWidth)) {
                    x = bounds.right - this.viewPortWidth;
                    x += nodePadding;
                }
                Iif (bounds.x < -hoffset) {
                    x = bounds.x;
                }
                Iif (bounds.bottom > (-voffset + this.viewPortHeight)) {
                    y = bounds.bottom - this.viewPortHeight;
                    y += nodePadding;
                }
                Eif (bounds.y < -voffset) {
                    y = bounds.y;
                }
                this.zoom(1, -this.horizontalOffset - x, -this.verticalOffset - y, null, undefined, isBringIntoView);
            }
        };
        DiagramScroller.prototype.bringToCenter = function (bounds) {
            var scale = this.currentZoom;
            var actualbounds = new rect_1.Rect(bounds.x * scale, bounds.y * scale, bounds.width * scale, bounds.height * scale);
            var hoffset = actualbounds.x + actualbounds.width / 2 - this.viewPortWidth / 2;
            var voffset = actualbounds.y + actualbounds.height / 2 - this.viewPortHeight / 2;
            hoffset *= -1;
            voffset *= -1;
            this.zoom(1, -this.horizontalOffset - hoffset, -this.verticalOffset - voffset, null);
        };
        DiagramScroller.prototype.applyScrollLimit = function (hOffset, vOffset, isInteractiveZoomPan, isBringIntoView, isTrackpadScroll) {
            if (this.diagram.scrollSettings.scrollLimit === 'Infinity') {
                if (isInteractiveZoomPan === undefined && !isBringIntoView) {
                    hOffset = -hOffset;
                    vOffset = -vOffset;
                }
            }
            if (this.diagram.scrollSettings.scrollLimit !== 'Infinity') {
                var bounds = void 0;
                if (this.diagram.scrollSettings.scrollLimit === 'Limited') {
                    var scrollableBounds = this.diagram.scrollSettings.scrollableArea;
                    bounds = new rect_1.Rect(scrollableBounds.x, scrollableBounds.y, scrollableBounds.width, scrollableBounds.height);
                }
                bounds = bounds || (isTrackpadScroll ? this.getPageBounds() : this.getPageBounds(true));
                bounds.x *= this.currentZoom;
                bounds.y *= this.currentZoom;
                bounds.width *= this.currentZoom;
                bounds.height *= this.currentZoom;
                if (isInteractiveZoomPan !== undefined) {
                    hOffset *= -1;
                    vOffset *= -1;
                }
                if (isBringIntoView) {
                    hOffset *= -1;
                    vOffset *= -1;
                }
                var allowedRight = Math.max(bounds.right, this.viewPortWidth);
                if (!isBringIntoView && !(hOffset <= bounds.x && (hOffset + this.viewPortWidth >= bounds.right ||
                    hOffset >= bounds.right - this.viewPortWidth)
                    || hOffset >= bounds.x && (hOffset + this.viewPortWidth <= allowedRight))) {
                    if (hOffset >= bounds.x) {
                        hOffset = Math.max(bounds.x, Math.min(hOffset, hOffset - (hOffset + this.viewPortWidth - this.vScrollSize - allowedRight)));
                    }
                    else {
                        var allowed = bounds.right - this.viewPortWidth;
                        hOffset = Math.min(allowed, bounds.x);
                    }
                }
                var allowedBottom = Math.max(bounds.bottom, this.viewPortHeight);
                if (!isBringIntoView && !(vOffset <= bounds.y && vOffset + this.viewPortHeight >= bounds.bottom
                    || vOffset >= bounds.y && vOffset + this.viewPortHeight <= allowedBottom)) {
                    Eif (vOffset >= bounds.y) {
                        vOffset = Math.max(bounds.y, Math.min(vOffset, vOffset - (vOffset + this.viewPortHeight - this.hScrollSize - allowedBottom)));
                    }
                    else {
                        var allowed = bounds.bottom - this.viewPortHeight;
                        vOffset = Math.min(bounds.y, allowed);
                    }
                }
                hOffset *= -1;
                vOffset *= -1;
            }
            return { x: hOffset, y: vOffset };
        };
        return DiagramScroller;
    }());
    exports.DiagramScroller = DiagramScroller;
});