2 * $Id: Shapes.js,v 1.13 2013-02-02 06:44:30 gaudenz Exp $
3 * Copyright (c) 2006-2012, JGraph Ltd
11 // Cube Shape, supports size style
12 function CubeShape() { };
13 CubeShape.prototype = new mxCylinder();
14 CubeShape.prototype.constructor = CubeShape;
15 CubeShape.prototype.size = 20;
16 CubeShape.prototype.redrawPath = function(path, x, y, w, h, isForeground)
18 var s = Math.min(w, Math.min(h, mxUtils.getValue(this.style, 'size', this.size)));
32 path.lineTo(w - s, 0);
36 path.lineTo(0, h - s);
43 mxCellRenderer.prototype.defaultShapes['cube'] = CubeShape;
45 // Note Shape, supports size style
46 function NoteShape() { };
47 NoteShape.prototype = new mxCylinder();
48 NoteShape.prototype.constructor = NoteShape;
49 NoteShape.prototype.size = 30;
50 NoteShape.prototype.redrawPath = function(path, x, y, w, h, isForeground)
52 var s = Math.min(w, Math.min(h, mxUtils.getValue(this.style, 'size', this.size)));
56 path.moveTo(w - s, 0);
57 path.lineTo(w - s, s);
64 path.lineTo(w - s, 0);
74 mxCellRenderer.prototype.defaultShapes['note'] = NoteShape;
76 // Folder Shape, supports tabWidth, tabHeight styles
77 function FolderShape() { };
78 FolderShape.prototype = new mxCylinder();
79 FolderShape.prototype.constructor = FolderShape;
80 FolderShape.prototype.tabWidth = 60;
81 FolderShape.prototype.tabHeight = 20;
82 FolderShape.prototype.tabPosition = 'right';
83 FolderShape.prototype.redrawPath = function(path, x, y, w, h, isForeground)
85 var tw = mxUtils.getValue(this.style, 'tabWidth', this.tabWidth);
86 var th = mxUtils.getValue(this.style, 'tabHeight', this.tabHeight);
87 var tp = mxUtils.getValue(this.style, 'tabPosition', this.tabPosition);
88 var dx = Math.min(w, tw);
89 var dy = Math.min(h, th);
101 path.moveTo(w - dx, dy);
120 path.lineTo(w - dx, dy);
121 path.lineTo(w - dx, 0);
133 mxCellRenderer.prototype.defaultShapes['folder'] = FolderShape;
135 // Card Shape, supports size style
136 function CardShape() { };
137 CardShape.prototype = new mxCylinder();
138 CardShape.prototype.constructor = CardShape;
139 CardShape.prototype.size = 30;
140 CardShape.prototype.redrawPath = function(path, x, y, w, h, isForeground)
142 var s = Math.min(w, Math.min(h, mxUtils.getValue(this.style, 'size', this.size)));
157 mxCellRenderer.prototype.defaultShapes['card'] = CardShape;
159 // Tape Shape, supports size style
160 function TapeShape() { };
161 TapeShape.prototype = new mxCylinder();
162 TapeShape.prototype.constructor = TapeShape;
163 TapeShape.prototype.size = 0.4;
164 TapeShape.prototype.redrawPath = function(path, x, y, w, h, isForeground)
166 var s = mxUtils.getValue(this.style, 'size', this.size);
172 path.moveTo(0, dy / 2);
173 path.quadTo(w / 4, dy * fy, w / 2, dy / 2);
174 path.quadTo(w * 3 / 4, dy * (1 - fy), w, dy / 2);
175 path.lineTo(w, h - dy / 2);
176 path.quadTo(w * 3 / 4, h - dy * fy, w / 2, h - dy / 2);
177 path.quadTo(w / 4, h - dy * (1 - fy), 0, h - dy / 2);
178 path.lineTo(0, dy / 2);
184 mxCellRenderer.prototype.defaultShapes['tape'] = TapeShape;
186 // Tape Shape, supports size style
187 function StepShape() { };
188 StepShape.prototype = new mxCylinder();
189 StepShape.prototype.constructor = StepShape;
190 StepShape.prototype.size = 0.2;
191 StepShape.prototype.redrawPath = function(path, x, y, w, h, isForeground)
193 var s = w * mxUtils.getValue(this.style, 'size', this.size);
198 path.lineTo(w - s, 0);
199 path.lineTo(w, h / 2);
200 path.lineTo(w - s, h);
202 path.lineTo(s, h / 2);
208 mxCellRenderer.prototype.defaultShapes['step'] = StepShape;
213 mxRectangleShape.call(this);
215 mxUtils.extend(PlusShape, mxRectangleShape);
216 PlusShape.prototype.isHtmlAllowed = function()
220 PlusShape.prototype.paintForeground = function(c, x, y, w, h)
222 var border = Math.min(w / 5, h / 5) + 1;
225 c.moveTo(x + w / 2, y + border);
226 c.lineTo(x + w / 2, y + h - border);
227 c.moveTo(x + border, y + h / 2);
228 c.lineTo(x + w - border, y + h / 2);
231 mxRectangleShape.prototype.paintForeground.apply(this, arguments);
234 mxCellRenderer.prototype.defaultShapes['plus'] = PlusShape;
237 function ExtendedShape()
239 mxRectangleShape.call(this);
241 mxUtils.extend(ExtendedShape, mxRectangleShape);
242 ExtendedShape.prototype.isHtmlAllowed = function()
246 ExtendedShape.prototype.paintForeground = function(c, x, y, w, h)
248 if (this.style != null)
250 if (this.style['double'] == 1)
252 var inset = Math.max(2, this.strokewidth + 1);
254 mxRectangleShape.prototype.paintBackground.call(this, c, x + inset, y + inset, w - 2 * inset, h - 2 * inset);
255 mxRectangleShape.prototype.paintForeground.apply(this, arguments);
265 // Draws the symbols defined in the style. The symbols are
266 // numbered from 1...n. Possible postfixes are align,
267 // verticalAlign, spacing, arcSpacing, width, height
273 shape = mxCellRenderer.prototype.defaultShapes[this.style['symbol' + counter]];
277 var align = this.style['symbol' + counter + 'Align'];
278 var valign = this.style['symbol' + counter + 'VerticalAlign'];
279 var width = this.style['symbol' + counter + 'Width'];
280 var height = this.style['symbol' + counter + 'Height'];
281 var spacing = this.style['symbol' + counter + 'Spacing'] || 0;
282 var arcspacing = this.style['symbol' + counter + 'ArcSpacing'];
284 if (arcspacing != null)
286 spacing += this.getArcSize(w + this.strokewidth, h + this.strokewidth) * arcspacing;
292 if (align == mxConstants.ALIGN_CENTER)
294 x2 += (w - width) / 2;
296 else if (align == mxConstants.ALIGN_RIGHT)
298 x2 += w - width - spacing;
305 if (valign == mxConstants.ALIGN_MIDDLE)
307 y2 += (h - height) / 2;
309 else if (valign == mxConstants.ALIGN_BOTTOM)
311 y2 += h - height - spacing;
320 // Small hack to pass style along into subshape
321 var tmp = new shape();
322 // TODO: Clone style and override settings (eg. strokewidth)
323 tmp.style = this.style;
324 shape.prototype.paintVertexShape.call(tmp, c, x2, y2, width, height);
330 while (shape != null);
334 mxCellRenderer.prototype.defaultShapes['ext'] = ExtendedShape;
336 // Tape Shape, supports size style
337 function MessageShape() { };
338 MessageShape.prototype = new mxCylinder();
339 MessageShape.prototype.constructor = MessageShape;
340 MessageShape.prototype.redrawPath = function(path, x, y, w, h, isForeground)
345 path.lineTo(w / 2, h / 2);
359 mxCellRenderer.prototype.defaultShapes['message'] = MessageShape;
362 function UmlActorShape() { };
363 UmlActorShape.prototype = new mxCylinder();
364 UmlActorShape.prototype.constructor = UmlActorShape;
365 UmlActorShape.prototype.addPipe = true;
366 UmlActorShape.prototype.redrawPath = function(path, x, y, w, h, isForeground)
373 path.moveTo(w / 2, height);
374 path.curveTo(w / 2 - width, height, w / 2 - width, 0, w / 2, 0);
375 path.curveTo(w / 2 + width, 0, w / 2 + width, height, w / 2, height);
378 path.moveTo(w / 2, height);
379 path.lineTo(w / 2, 2 * h / 3);
382 path.moveTo(w / 2, h / 3);
383 path.lineTo(0, h / 3);
384 path.moveTo(w / 2, h / 3);
385 path.lineTo(w, h / 3);
388 path.moveTo(w / 2, 2 * h / 3);
390 path.moveTo(w / 2, 2 * h / 3);
396 // Replaces existing actor shape
397 mxCellRenderer.prototype.defaultShapes['umlActor'] = UmlActorShape;
400 function LollipopShape() { };
401 LollipopShape.prototype = new mxCylinder();
402 LollipopShape.prototype.constructor = LollipopShape;
403 LollipopShape.prototype.size = 10;
404 LollipopShape.prototype.addPipe = true;
405 LollipopShape.prototype.redrawPath = function(path, x, y, w, h, isForeground)
407 var ss = mxUtils.getValue(this.style, 'size', this.size);
408 var width = ss * 2 / 3;
413 path.moveTo(w / 2, height);
414 path.curveTo(w / 2 - width, height, w / 2 - width, 0, w / 2, 0);
415 path.curveTo(w / 2 + width, 0, w / 2 + width, height, w / 2, height);
418 path.moveTo(w / 2, height);
419 path.lineTo(w / 2, h);
424 // Replaces existing actor shape
425 mxCellRenderer.prototype.defaultShapes['lollipop'] = LollipopShape;
427 // Folder Shape, supports tabWidth, tabHeight styles
428 function ComponentShape() { };
429 ComponentShape.prototype = new mxCylinder();
430 ComponentShape.prototype.constructor = ComponentShape;
431 ComponentShape.prototype.jettyWidth = 32;
432 ComponentShape.prototype.jettyHeight = 12;
433 ComponentShape.prototype.redrawPath = function(path, x, y, w, h, isForeground)
435 var dx = mxUtils.getValue(this.style, 'jettyWidth', this.jettyWidth);
436 var dy = mxUtils.getValue(this.style, 'jettyHeight', this.jettyHeight);
438 var x1 = x0 + dx / 2;
439 var y0 = 0.3 * h - dy / 2;
440 var y1 = 0.7 * h - dy / 2;
446 path.lineTo(x1, y0 + dy);
447 path.lineTo(x0, y0 + dy);
450 path.lineTo(x1, y1 + dy);
451 path.lineTo(x0, y1 + dy);
460 path.lineTo(x0, y1 + dy);
461 path.lineTo(0, y1 + dy);
464 path.lineTo(x0, y0 + dy);
465 path.lineTo(0, y0 + dy);
473 mxCellRenderer.prototype.defaultShapes['component'] = ComponentShape;
475 // State Shapes derives from double ellipse
476 function StateShape() { };
477 StateShape.prototype = new mxDoubleEllipse();
478 StateShape.prototype.constructor = StateShape;
479 StateShape.prototype.outerStroke = true;
480 StateShape.prototype.paintVertexShape = function(c, x, y, w, h)
482 var inset = Math.min(4, Math.min(w / 5, h / 5));
486 c.ellipse(x + inset, y + inset, w - 2 * inset, h - 2 * inset);
492 if (this.outerStroke)
494 c.ellipse(x, y, w, h);
499 mxCellRenderer.prototype.defaultShapes['endState'] = StateShape;
501 function StartStateShape() { };
502 StartStateShape.prototype = new StateShape();
503 StartStateShape.prototype.constructor = StartStateShape;
504 StartStateShape.prototype.outerStroke = false;
506 mxCellRenderer.prototype.defaultShapes['startState'] = StartStateShape;
508 // Image export for state shapes
509 var imageExportInitShapes = mxImageExport.prototype.initShapes;
510 mxImageExport.prototype.initShapes = function()
512 imageExportInitShapes.apply(this, arguments);
514 function createStateShape(outerStroke)
517 drawShape: function(canvas, state, bounds, background)
521 var w = bounds.width;
522 var h = bounds.height;
526 var inset = Math.min(4, Math.min(w / 5, h / 5));
534 canvas.ellipse(x, y, w, h);
541 canvas.fillAndStroke();
545 canvas.ellipse(x, y, w, h);
553 this.shapes['endState'] = createStateShape(true);
554 this.shapes['startState'] = createStateShape(false);
557 // Defines custom edge shape
562 mxUtils.extend(LinkShape, mxArrow);
563 LinkShape.prototype.paintEdgeShape = function(c, pts)
567 // Base vector (between end points)
569 var pe = pts[pts.length - 1];
571 var dx = pe.x - p0.x;
572 var dy = pe.y - p0.y;
573 var dist = Math.sqrt(dx * dx + dy * dy);
576 // Computes the norm and the inverse norm
579 var basex = length * nx;
580 var basey = length * ny;
581 var floorx = width * ny/3;
582 var floory = -width * nx/3;
585 var p0x = p0.x - floorx / 2;
586 var p0y = p0.y - floory / 2;
587 var p1x = p0x + floorx;
588 var p1y = p0y + floory;
589 var p2x = p1x + basex;
590 var p2y = p1y + basey;
591 var p3x = p2x + floorx;
592 var p3y = p2y + floory;
594 var p5x = p3x - 3 * floorx;
595 var p5y = p3y - 3 * floory;
600 c.moveTo(p5x + floorx, p5y + floory);
605 // Registers the link shape
606 mxCellRenderer.prototype.defaultShapes['link'] = LinkShape;
608 // Registers and defines the custom marker
609 mxMarker.addMarker('dash', function(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled)
611 var nx = unitX * (size + sw + 1);
612 var ny = unitY * (size + sw + 1);
617 canvas.moveTo(pe.x - nx / 2 - ny / 2, pe.y - ny / 2 + nx / 2);
618 canvas.lineTo(pe.x + ny / 2 - 3 * nx / 2, pe.y - 3 * ny / 2 - nx / 2);
623 // Implements custom handlers
624 var SPECIAL_HANDLE_INDEX = -99;
626 // Handlers are only added if mxVertexHandler is defined (ie. not in embedded graph)
627 if (typeof(mxVertexHandler) != 'undefined')
629 function mxExtVertexHandler(state)
631 mxVertexHandler.call(this, state);
634 mxUtils.extend(mxExtVertexHandler, mxVertexHandler);
636 mxExtVertexHandler.prototype.useGridForSpecialHandle = false;
638 mxExtVertexHandler.prototype.init = function()
640 this.horizontal = mxUtils.getValue(this.state.style, mxConstants.STYLE_HORIZONTAL, true);
641 var graph = this.state.view.graph;
643 if (this.handleImage != null)
645 var bounds = new mxRectangle(0, 0, this.handleImage.width, this.handleImage.height);
646 this.specialHandle = new mxImageShape(bounds, this.handleImage.src);
651 var bounds = new mxRectangle(0, 0, size, size);
652 this.specialHandle = new mxRhombus(bounds, mxConstants.HANDLE_FILLCOLOR, mxConstants.HANDLE_STROKECOLOR);
655 this.specialHandle.dialect = (graph.dialect != mxConstants.DIALECT_SVG) ?
656 mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG;
657 this.specialHandle.init(graph.getView().getOverlayPane());
658 this.specialHandle.node.style.cursor = this.getSpecialHandleCursor();
660 mxEvent.redirectMouseEvents(this.specialHandle.node, graph, this.state);
661 mxVertexHandler.prototype.init.apply(this, arguments);
664 mxExtVertexHandler.prototype.getSpecialHandleCursor = function()
669 mxExtVertexHandler.prototype.redraw = function()
671 mxVertexHandler.prototype.redraw.apply(this, arguments);
673 var size = this.specialHandle.bounds.width;
674 this.specialHandle.bounds = this.getSpecialHandleBounds(size);
675 this.specialHandle.redraw();
678 mxExtVertexHandler.prototype.destroy = function()
680 mxVertexHandler.prototype.destroy.apply(this, arguments);
682 if (this.specialHandle != null)
684 this.specialHandle.destroy();
685 this.specialHandle = null;
689 mxExtVertexHandler.prototype.getHandleForEvent = function(me)
691 if (me.isSource(this.specialHandle))
693 return SPECIAL_HANDLE_INDEX;
696 return mxVertexHandler.prototype.getHandleForEvent.apply(this, arguments);
699 mxExtVertexHandler.prototype.mouseMove = function(sender, me)
701 if (!me.isConsumed() && this.index == SPECIAL_HANDLE_INDEX)
703 var point = new mxPoint(me.getGraphX(), me.getGraphY());
704 this.constrainPoint(point);
705 var gridEnabled = this.graph.isGridEnabledEvent(me.getEvent());
706 var scale = this.graph.getView().scale;
708 if (gridEnabled && this.useGridForSpecialHandle)
710 point.x = this.graph.snap(point.x / scale) * scale;
711 point.y = this.graph.snap(point.y / scale) * scale;
714 this.updateStyle(point);
715 this.moveSizerTo(this.specialHandle, point.x, point.y);
716 this.state.view.graph.cellRenderer.redraw(this.state, true);
721 mxVertexHandler.prototype.mouseMove.apply(this, arguments);
725 mxExtVertexHandler.prototype.mouseUp = function(sender, me)
727 if (!me.isConsumed() && this.index == SPECIAL_HANDLE_INDEX)
735 mxVertexHandler.prototype.mouseUp.apply(this, arguments);
739 mxExtVertexHandler.prototype.getSpecialHandleBounds = function(size)
741 var rotation = this.state.shape.getShapeRotation();
742 var alpha = mxUtils.toRadians(rotation);
743 var cos = Math.cos(alpha);
744 var sin = Math.sin(alpha);
746 var bounds = new mxRectangle(this.state.x, this.state.y, this.state.width, this.state.height);
748 if (this.state.shape.isPaintBoundsInverted())
750 var t = (bounds.width - bounds.height) / 2;
753 var tmp = bounds.width;
754 bounds.width = bounds.height;
758 var pt = this.getSpecialHandlePoint(bounds);
760 if (this.state.shape.flipH)
762 pt.x = 2 * bounds.x + bounds.width - pt.x;
765 if (this.state.shape.flipV)
767 pt.y = 2 * bounds.y + bounds.height - pt.y;
770 pt = mxUtils.getRotatedPoint(pt, cos, sin,
771 new mxPoint(this.state.getCenterX(), this.state.getCenterY()));
773 return new mxRectangle(pt.x - size / 2, pt.y - size / 2, size, size);
776 mxExtVertexHandler.prototype.getSpecialHandlePoint = function(bounds)
778 // Hook for subclassers
782 mxExtVertexHandler.prototype.updateStyle = function(point)
784 // Hook for subclassers
787 mxExtVertexHandler.prototype.constrainPoint = function(point)
789 point.x = Math.max(this.state.x, Math.min(this.state.x + this.state.width, point.x));
790 point.y = Math.max(this.state.y, Math.min(this.state.y + this.state.height, point.y));
793 mxExtVertexHandler.prototype.applyStyle = function()
795 // Hook for subclassers
799 function mxFolderHandler(state)
801 mxExtVertexHandler.call(this, state);
804 mxUtils.extend(mxFolderHandler, mxExtVertexHandler);
806 mxFolderHandler.prototype.getSpecialHandlePoint = function(bounds)
808 var scale = this.graph.getView().scale;
809 var tw = Math.min(bounds.width, mxUtils.getValue(this.state.style, 'tabWidth', 60) * scale);
810 var th = Math.min(bounds.height, mxUtils.getValue(this.state.style, 'tabHeight', 20) * scale);
812 var tp = mxUtils.getValue(this.state.style, 'tabPosition', 'right');
813 var x = (tp == 'left') ? bounds.x + tw : bounds.x + bounds.width - tw;
815 return new mxPoint(x, bounds.y + th);
818 mxFolderHandler.prototype.updateStyle = function(point)
820 var rotation = this.state.shape.getShapeRotation();
821 var alpha = mxUtils.toRadians(rotation);
822 var cos = Math.cos(-alpha);
823 var sin = Math.sin(-alpha);
825 var bounds = new mxRectangle(this.state.x, this.state.y, this.state.width, this.state.height);
827 if (this.state.shape.isPaintBoundsInverted())
829 var t = (bounds.width - bounds.height) / 2;
832 var tmp = bounds.width;
833 bounds.width = bounds.height;
837 var pt = new mxPoint(point.x, point.y);
838 pt = mxUtils.getRotatedPoint(pt, cos, sin,
839 new mxPoint(this.state.getCenterX(), this.state.getCenterY()));
841 if (this.state.shape.flipH)
843 pt.x = 2 * bounds.x + bounds.width - pt.x;
846 if (this.state.shape.flipV)
848 pt.y = 2 * bounds.y + bounds.height - pt.y;
851 var result = this.updateStyleUnrotated(pt, bounds);
853 // Modifies point to use rotated coordinates of return value
856 if (this.state.shape.flipH)
858 result.x = 2 * bounds.x + bounds.width - result.x;
861 if (this.state.shape.flipV)
863 result.y = 2 * bounds.y + bounds.height - result.y;
866 cos = Math.cos(alpha);
867 sin = Math.sin(alpha);
868 result = mxUtils.getRotatedPoint(result, cos, sin,
869 new mxPoint(this.state.getCenterX(), this.state.getCenterY()));
875 mxFolderHandler.prototype.updateStyleUnrotated = function(pt, bounds)
877 var tp = mxUtils.getValue(this.state.style, 'tabPosition', 'right');
878 var tw = (tp == 'left') ? pt.x - bounds.x : bounds.x + bounds.width - pt.x;
879 var th = pt.y - bounds.y;
881 var scale = this.graph.getView().scale;
882 this.state.style['tabWidth'] = Math.round(Math.max(1, tw) / scale);
883 this.state.style['tabHeight'] = Math.round(Math.max(1, th) / scale);
886 mxFolderHandler.prototype.applyStyle = function()
888 var model = this.graph.getModel();
892 this.state.view.graph.setCellStyles('tabWidth', this.state.style['tabWidth'], [this.state.cell]);
893 this.state.view.graph.setCellStyles('tabHeight', this.state.style['tabHeight'], [this.state.cell]);
902 function mxSwimlaneHandler(state)
904 mxFolderHandler.call(this, state);
907 mxUtils.extend(mxSwimlaneHandler, mxFolderHandler);
909 mxSwimlaneHandler.prototype.getSpecialHandlePoint = function(bounds)
911 var scale = this.graph.getView().scale;
912 var startSize = mxUtils.getValue(this.state.style, mxConstants.STYLE_STARTSIZE, mxConstants.DEFAULT_STARTSIZE);
914 return new mxPoint(bounds.x + bounds.width / 2, bounds.y + Math.min(bounds.height, startSize * scale));
917 mxSwimlaneHandler.prototype.updateStyleUnrotated = function(point, bounds)
919 point.x = bounds.x + bounds.width / 2;
920 startSize = point.y - bounds.y;
921 var scale = this.graph.getView().scale;
922 this.state.style['startSize'] = Math.round(Math.max(1, startSize) / scale);
927 mxSwimlaneHandler.prototype.applyStyle = function()
929 this.state.view.graph.setCellStyles('startSize', this.state.style['startSize'], [this.state.cell]);
933 function mxCubeHandler(state)
935 mxFolderHandler.call(this, state);
938 mxUtils.extend(mxCubeHandler, mxFolderHandler);
940 mxCubeHandler.prototype.defaultValue = 20;
942 mxCubeHandler.prototype.scaleFactor = 1;
944 mxCubeHandler.prototype.getSpecialHandlePoint = function(bounds)
946 var scale = this.graph.getView().scale;
947 var sz = Math.min(bounds.width, Math.min(bounds.height,
948 mxUtils.getValue(this.state.style, 'size', this.defaultValue) * scale / this.scaleFactor));
950 return new mxPoint(bounds.x + sz, bounds.y + sz);
953 mxCubeHandler.prototype.updateStyleUnrotated = function(pt, bounds)
955 var size = Math.max(0, Math.min(Math.min(bounds.width / this.scaleFactor, pt.x - bounds.x),
956 Math.min(bounds.height / this.scaleFactor, pt.y - bounds.y)));
957 var scale = this.graph.getView().scale;
958 this.state.style['size'] = Math.round(Math.max(1, size) / scale) * this.scaleFactor;
960 // Stays on the diagonal
961 return new mxPoint(bounds.x + size, bounds.y + size);
964 mxCubeHandler.prototype.applyStyle = function()
966 this.state.view.graph.setCellStyles('size', this.state.style['size'], [this.state.cell]);
970 function mxCardHandler(state)
972 mxCubeHandler.call(this, state);
975 mxUtils.extend(mxCardHandler, mxCubeHandler);
977 mxCardHandler.prototype.defaultValue = 30;
979 mxCardHandler.prototype.scaleFactor = 2;
982 function mxNoteHandler(state)
984 mxCubeHandler.call(this, state);
987 mxUtils.extend(mxNoteHandler, mxCubeHandler);
989 mxNoteHandler.prototype.defaultValue = 30;
991 mxNoteHandler.prototype.scaleFactor = 1;
993 mxNoteHandler.prototype.getSpecialHandlePoint = function(bounds)
995 var scale = this.graph.getView().scale;
996 var sz = Math.min(bounds.width, Math.min(bounds.height,
997 mxUtils.getValue(this.state.style, 'size', this.defaultValue) * scale / this.scaleFactor));
999 return new mxPoint(bounds.x + bounds.width - sz, bounds.y + sz);
1002 mxNoteHandler.prototype.updateStyleUnrotated = function(pt, bounds)
1004 var size = Math.max(0, Math.min(Math.min(bounds.width / this.scaleFactor, pt.x - bounds.x + bounds.width),
1005 Math.min(bounds.height / this.scaleFactor, pt.y - bounds.y)));
1006 var scale = this.graph.getView().scale;
1007 this.state.style['size'] = Math.round(Math.max(1, size) / scale) * this.scaleFactor;
1009 // Stays on the diagonal
1010 return new mxPoint(bounds.x + bounds.width - size, bounds.y + size);
1014 function mxStepHandler(state)
1016 mxCubeHandler.call(this, state);
1019 mxUtils.extend(mxStepHandler, mxCubeHandler);
1021 mxStepHandler.prototype.defaultValue = 0.2;
1023 mxStepHandler.prototype.scaleFactor = 1;
1025 mxStepHandler.prototype.getSpecialHandlePoint = function(bounds)
1027 var sz = mxUtils.getValue(this.state.style, 'size', this.defaultValue);
1029 return new mxPoint(bounds.x + bounds.width * sz, bounds.y + bounds.height / 2);
1032 mxStepHandler.prototype.updateStyleUnrotated = function(pt, bounds)
1034 var size = Math.min(1, (pt.x - bounds.x) / bounds.width);
1035 this.state.style['size'] = size;
1037 return new mxPoint(bounds.x + size * bounds.width, bounds.y + bounds.height / 2);
1041 function mxTapeHandler(state)
1043 mxCubeHandler.call(this, state);
1046 mxUtils.extend(mxTapeHandler, mxCubeHandler);
1048 mxTapeHandler.prototype.defaultValue = 0.4;
1050 mxTapeHandler.prototype.scaleFactor = 1;
1052 mxTapeHandler.prototype.getSpecialHandlePoint = function(bounds)
1054 var sz = mxUtils.getValue(this.state.style, 'size', this.defaultValue);
1056 return new mxPoint(bounds.x + bounds.width / 2, bounds.y + sz * bounds.height / 2);
1059 mxTapeHandler.prototype.updateStyleUnrotated = function(pt, bounds)
1061 var size = Math.max(0, Math.min(1, ((pt.y - bounds.y) / bounds.height) * 2));
1062 this.state.style['size'] = size;
1064 return new mxPoint(bounds.x + bounds.width / 2, bounds.y + size * bounds.height / 2);
1067 var handlers = {'swimlane': mxSwimlaneHandler, 'folder': mxFolderHandler, 'cube': mxCubeHandler,
1068 'card': mxCardHandler, 'note': mxNoteHandler, 'step': mxStepHandler, 'tape': mxTapeHandler};
1070 var mxGraphCreateHandler = mxGraph.prototype.createHandler;
1071 mxGraph.prototype.createHandler = function(state)
1075 var ctor = handlers[state.style['shape']];
1079 return new ctor(state);
1083 return mxGraphCreateHandler.apply(this, arguments);
1088 mxGraph.prototype.getAllConnectionConstraints = function(terminal, source)
1090 if (terminal != null && terminal.shape != null)
1092 if (terminal.shape.stencil != null)
1094 if (terminal.shape.stencil != null)
1096 return terminal.shape.stencil.constraints;
1099 else if (terminal.shape.constraints != null)
1101 return terminal.shape.constraints;
1108 mxRectangleShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.25, 0), true),
1109 new mxConnectionConstraint(new mxPoint(0.5, 0), true),
1110 new mxConnectionConstraint(new mxPoint(0.75, 0), true),
1111 new mxConnectionConstraint(new mxPoint(0, 0.25), true),
1112 new mxConnectionConstraint(new mxPoint(0, 0.5), true),
1113 new mxConnectionConstraint(new mxPoint(0, 0.75), true),
1114 new mxConnectionConstraint(new mxPoint(1, 0.25), true),
1115 new mxConnectionConstraint(new mxPoint(1, 0.5), true),
1116 new mxConnectionConstraint(new mxPoint(1, 0.75), true),
1117 new mxConnectionConstraint(new mxPoint(0.25, 1), true),
1118 new mxConnectionConstraint(new mxPoint(0.5, 1), true),
1119 new mxConnectionConstraint(new mxPoint(0.75, 1), true)];
1120 mxLabel.prototype.constraints = mxRectangleShape.prototype.constraints;
1121 mxImageShape.prototype.constraints = mxRectangleShape.prototype.constraints;
1122 mxSwimlane.prototype.constraints = mxRectangleShape.prototype.constraints;
1123 PlusShape.prototype.constraints = mxRectangleShape.prototype.constraints;
1124 NoteShape.prototype.constraints = mxRectangleShape.prototype.constraints;
1125 CardShape.prototype.constraints = mxRectangleShape.prototype.constraints;
1126 CubeShape.prototype.constraints = mxRectangleShape.prototype.constraints;
1127 FolderShape.prototype.constraints = mxRectangleShape.prototype.constraints;
1128 mxCylinder.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.15, 0.05), false),
1129 new mxConnectionConstraint(new mxPoint(0.5, 0), true),
1130 new mxConnectionConstraint(new mxPoint(0.85, 0.05), false),
1131 new mxConnectionConstraint(new mxPoint(0, 0.3), true),
1132 new mxConnectionConstraint(new mxPoint(0, 0.5), true),
1133 new mxConnectionConstraint(new mxPoint(0, 0.7), true),
1134 new mxConnectionConstraint(new mxPoint(1, 0.3), true),
1135 new mxConnectionConstraint(new mxPoint(1, 0.5), true),
1136 new mxConnectionConstraint(new mxPoint(1, 0.7), true),
1137 new mxConnectionConstraint(new mxPoint(0.15, 0.95), false),
1138 new mxConnectionConstraint(new mxPoint(0.5, 1), true),
1139 new mxConnectionConstraint(new mxPoint(0.85, 0.95), false)];
1140 UmlActorShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.25, 0.1), false),
1141 new mxConnectionConstraint(new mxPoint(0.5, 0), false),
1142 new mxConnectionConstraint(new mxPoint(0.75, 0.1), false),
1143 new mxConnectionConstraint(new mxPoint(0, 1/3), false),
1144 new mxConnectionConstraint(new mxPoint(0, 1), false),
1145 new mxConnectionConstraint(new mxPoint(1, 1/3), false),
1146 new mxConnectionConstraint(new mxPoint(1, 1), false),
1147 new mxConnectionConstraint(new mxPoint(0.5, 0.5), false)];
1148 ComponentShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.25, 0), true),
1149 new mxConnectionConstraint(new mxPoint(0.5, 0), true),
1150 new mxConnectionConstraint(new mxPoint(0.75, 0), true),
1151 new mxConnectionConstraint(new mxPoint(0, 0.3), true),
1152 new mxConnectionConstraint(new mxPoint(0, 0.7), true),
1153 new mxConnectionConstraint(new mxPoint(1, 0.25), true),
1154 new mxConnectionConstraint(new mxPoint(1, 0.5), true),
1155 new mxConnectionConstraint(new mxPoint(1, 0.75), true),
1156 new mxConnectionConstraint(new mxPoint(0.25, 1), true),
1157 new mxConnectionConstraint(new mxPoint(0.5, 1), true),
1158 new mxConnectionConstraint(new mxPoint(0.75, 1), true)];
1159 mxActor.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.5, 0), true),
1160 new mxConnectionConstraint(new mxPoint(0.25, 0.2), false),
1161 new mxConnectionConstraint(new mxPoint(0.1, 0.5), false),
1162 new mxConnectionConstraint(new mxPoint(0, 0.75), true),
1163 new mxConnectionConstraint(new mxPoint(0.75, 0.25), false),
1164 new mxConnectionConstraint(new mxPoint(0.9, 0.5), false),
1165 new mxConnectionConstraint(new mxPoint(1, 0.75), true),
1166 new mxConnectionConstraint(new mxPoint(0.25, 1), true),
1167 new mxConnectionConstraint(new mxPoint(0.5, 1), true),
1168 new mxConnectionConstraint(new mxPoint(0.75, 1), true)];
1169 TapeShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0.35), false),
1170 new mxConnectionConstraint(new mxPoint(0, 0.5), false),
1171 new mxConnectionConstraint(new mxPoint(0, 0.65), false),
1172 new mxConnectionConstraint(new mxPoint(1, 0.35), false),
1173 new mxConnectionConstraint(new mxPoint(1, 0.5), false),
1174 new mxConnectionConstraint(new mxPoint(1, 0.65), false),
1175 new mxConnectionConstraint(new mxPoint(0.25, 1), false),
1176 new mxConnectionConstraint(new mxPoint(0.75, 0), false)];
1177 // TODO: Relative ports
1178 StepShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.25, 0), true),
1179 new mxConnectionConstraint(new mxPoint(0.5, 0), true),
1180 new mxConnectionConstraint(new mxPoint(0.75, 0), true),
1181 new mxConnectionConstraint(new mxPoint(0.25, 1), true),
1182 new mxConnectionConstraint(new mxPoint(0.5, 1), true),
1183 new mxConnectionConstraint(new mxPoint(0.75, 1), true),
1184 new mxConnectionConstraint(new mxPoint(0.1, 0.25), false),
1185 new mxConnectionConstraint(new mxPoint(0.2, 0.5), false),
1186 new mxConnectionConstraint(new mxPoint(0.1, 0.75), false),
1187 new mxConnectionConstraint(new mxPoint(0.9, 0.25), false),
1188 new mxConnectionConstraint(new mxPoint(1, 0.5), false),
1189 new mxConnectionConstraint(new mxPoint(0.9, 0.75), false)];
1190 mxLine.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0.5), false),
1191 new mxConnectionConstraint(new mxPoint(0.25, 0.5), false),
1192 new mxConnectionConstraint(new mxPoint(0.75, 0.5), false),
1193 new mxConnectionConstraint(new mxPoint(1, 0.5), false)];
1194 LollipopShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.5, 0), false),
1195 new mxConnectionConstraint(new mxPoint(0.5, 1), false)];
1196 mxEllipse.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0), true), new mxConnectionConstraint(new mxPoint(1, 0), true),
1197 new mxConnectionConstraint(new mxPoint(0, 1), true), new mxConnectionConstraint(new mxPoint(1, 1), true),
1198 new mxConnectionConstraint(new mxPoint(0.5, 0), true), new mxConnectionConstraint(new mxPoint(0.5, 1), true),
1199 new mxConnectionConstraint(new mxPoint(0, 0.5), true), new mxConnectionConstraint(new mxPoint(1, 0.5))];
1200 mxDoubleEllipse.prototype.constraints = mxEllipse.prototype.constraints;
1201 mxRhombus.prototype.constraints = mxEllipse.prototype.constraints;
1202 mxTriangle.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0.25), true),
1203 new mxConnectionConstraint(new mxPoint(0, 0.5), true),
1204 new mxConnectionConstraint(new mxPoint(0, 0.75), true),
1205 new mxConnectionConstraint(new mxPoint(0.5, 0), true),
1206 new mxConnectionConstraint(new mxPoint(0.5, 1), true),
1207 new mxConnectionConstraint(new mxPoint(1, 0.5), true)];
1208 mxHexagon.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.375, 0), true),
1209 new mxConnectionConstraint(new mxPoint(0.5, 0), true),
1210 new mxConnectionConstraint(new mxPoint(0.625, 0), true),
1211 new mxConnectionConstraint(new mxPoint(0.125, 0.25), false),
1212 new mxConnectionConstraint(new mxPoint(0, 0.5), true),
1213 new mxConnectionConstraint(new mxPoint(0.125, 0.75), false),
1214 new mxConnectionConstraint(new mxPoint(0.875, 0.25), false),
1215 new mxConnectionConstraint(new mxPoint(0, 0.5), true),
1216 new mxConnectionConstraint(new mxPoint(1, 0.5), true),
1217 new mxConnectionConstraint(new mxPoint(0.875, 0.75), false),
1218 new mxConnectionConstraint(new mxPoint(0.375, 1), true),
1219 new mxConnectionConstraint(new mxPoint(0.5, 1), true),
1220 new mxConnectionConstraint(new mxPoint(0.625, 1), true)];
1221 mxCloud.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.25, 0.25), false),
1222 new mxConnectionConstraint(new mxPoint(0.4, 0.1), false),
1223 new mxConnectionConstraint(new mxPoint(0.16, 0.55), false),
1224 new mxConnectionConstraint(new mxPoint(0.07, 0.4), false),
1225 new mxConnectionConstraint(new mxPoint(0.31, 0.8), false),
1226 new mxConnectionConstraint(new mxPoint(0.13, 0.77), false),
1227 new mxConnectionConstraint(new mxPoint(0.8, 0.8), false),
1228 new mxConnectionConstraint(new mxPoint(0.55, 0.95), false),
1229 new mxConnectionConstraint(new mxPoint(0.875, 0.5), false),
1230 new mxConnectionConstraint(new mxPoint(0.96, 0.7), false),
1231 new mxConnectionConstraint(new mxPoint(0.625, 0.2), false),
1232 new mxConnectionConstraint(new mxPoint(0.88, 0.25), false)];
1233 mxArrow.prototype.constraints = null;