1/** 2 * Copyright (c) 2006-2012, JGraph Ltd 3 */ 4/** 5 * Construcs a new sidebar for the given editor. 6 */ 7function Sidebar(editorUi, container) 8{ 9 this.editorUi = editorUi; 10 this.container = container; 11 this.palettes = new Object(); 12 this.taglist = new Object(); 13 this.lastCreated = 0; 14 this.showTooltips = true; 15 this.graph = editorUi.createTemporaryGraph(this.editorUi.editor.graph.getStylesheet()); 16 this.graph.cellRenderer.minSvgStrokeWidth = this.minThumbStrokeWidth; 17 this.graph.cellRenderer.antiAlias = this.thumbAntiAlias; 18 this.graph.container.style.visibility = 'hidden'; 19 this.graph.foldingEnabled = false; 20 21 document.body.appendChild(this.graph.container); 22 23 this.pointerUpHandler = mxUtils.bind(this, function() 24 { 25 if (this.tooltipCloseImage == null || this.tooltipCloseImage.style.display == 'none') 26 { 27 this.showTooltips = true; 28 this.hideTooltip(); 29 } 30 }); 31 32 mxEvent.addListener(document, (mxClient.IS_POINTER) ? 'pointerup' : 'mouseup', this.pointerUpHandler); 33 34 this.pointerDownHandler = mxUtils.bind(this, function() 35 { 36 if (this.tooltipCloseImage == null || this.tooltipCloseImage.style.display == 'none') 37 { 38 this.showTooltips = false; 39 this.hideTooltip(); 40 } 41 }); 42 43 mxEvent.addListener(document, (mxClient.IS_POINTER) ? 'pointerdown' : 'mousedown', this.pointerDownHandler); 44 45 this.pointerMoveHandler = mxUtils.bind(this, function(evt) 46 { 47 if (Date.now() - this.lastCreated > 300 && (this.tooltipCloseImage == null || 48 this.tooltipCloseImage.style.display == 'none')) 49 { 50 var src = mxEvent.getSource(evt); 51 52 while (src != null) 53 { 54 if (src == this.currentElt) 55 { 56 return; 57 } 58 59 src = src.parentNode; 60 } 61 62 this.hideTooltip(); 63 } 64 }); 65 66 mxEvent.addListener(document, (mxClient.IS_POINTER) ? 'pointermove' : 'mousemove', this.pointerMoveHandler); 67 68 // Handles mouse leaving the window 69 this.pointerOutHandler = mxUtils.bind(this, function(evt) 70 { 71 if (evt.toElement == null && evt.relatedTarget == null) 72 { 73 this.hideTooltip(); 74 } 75 }); 76 77 mxEvent.addListener(document, (mxClient.IS_POINTER) ? 'pointerout' : 'mouseout', this.pointerOutHandler); 78 79 // Enables tooltips after scroll 80 mxEvent.addListener(container, 'scroll', mxUtils.bind(this, function() 81 { 82 this.showTooltips = true; 83 this.hideTooltip(); 84 })); 85 86 this.init(); 87}; 88 89/** 90 * Adds all palettes to the sidebar. 91 */ 92Sidebar.prototype.init = function() 93{ 94 var dir = STENCIL_PATH; 95 96 this.addSearchPalette(true); 97 this.addGeneralPalette(true); 98 this.addMiscPalette(false); 99 this.addAdvancedPalette(false); 100 this.addBasicPalette(dir); 101 102 this.setCurrentSearchEntryLibrary('arrows'); 103 this.addStencilPalette('arrows', mxResources.get('arrows'), dir + '/arrows.xml', 104 ';whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;strokeWidth=2'); 105 this.setCurrentSearchEntryLibrary(); 106 107 this.addUmlPalette(false); 108 this.addBpmnPalette(dir, false); 109 110 this.setCurrentSearchEntryLibrary('flowchart'); 111 this.addStencilPalette('flowchart', 'Flowchart', dir + '/flowchart.xml', 112 ';whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;strokeWidth=2'); 113 this.setCurrentSearchEntryLibrary(); 114 115 this.setCurrentSearchEntryLibrary('clipart'); 116 this.addImagePalette('clipart', mxResources.get('clipart'), dir + '/clipart/', '_128x128.png', 117 ['Earth_globe', 'Empty_Folder', 'Full_Folder', 'Gear', 'Lock', 'Software', 'Virus', 'Email', 118 'Database', 'Router_Icon', 'iPad', 'iMac', 'Laptop', 'MacBook', 'Monitor_Tower', 'Printer', 119 'Server_Tower', 'Workstation', 'Firewall_02', 'Wireless_Router_N', 'Credit_Card', 120 'Piggy_Bank', 'Graph', 'Safe', 'Shopping_Cart', 'Suit1', 'Suit2', 'Suit3', 'Pilot1', 121 'Worker1', 'Soldier1', 'Doctor1', 'Tech1', 'Security1', 'Telesales1'], null, 122 {'Wireless_Router_N': 'wireless router switch wap wifi access point wlan', 123 'Router_Icon': 'router switch'}); 124 this.setCurrentSearchEntryLibrary(); 125}; 126 127/** 128 * Sets the default font size. 129 */ 130Sidebar.prototype.collapsedImage = (!mxClient.IS_SVG) ? IMAGE_PATH + '/collapsed.gif' : 'data:image/gif;base64,R0lGODlhDQANAIABAJmZmf///yH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IE1hY2ludG9zaCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDozNUQyRTJFNjZGNUYxMUU1QjZEOThCNDYxMDQ2MzNCQiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDozNUQyRTJFNzZGNUYxMUU1QjZEOThCNDYxMDQ2MzNCQiI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjFERjc3MEUxNkY1RjExRTVCNkQ5OEI0NjEwNDYzM0JCIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjFERjc3MEUyNkY1RjExRTVCNkQ5OEI0NjEwNDYzM0JCIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+Af/+/fz7+vn49/b19PPy8fDv7u3s6+rp6Ofm5eTj4uHg397d3Nva2djX1tXU09LR0M/OzczLysnIx8bFxMPCwcC/vr28u7q5uLe2tbSzsrGwr66trKuqqainpqWko6KhoJ+enZybmpmYl5aVlJOSkZCPjo2Mi4qJiIeGhYSDgoGAf359fHt6eXh3dnV0c3JxcG9ubWxramloZ2ZlZGNiYWBfXl1cW1pZWFdWVVRTUlFQT05NTEtKSUhHRkVEQ0JBQD8+PTw7Ojk4NzY1NDMyMTAvLi0sKyopKCcmJSQjIiEgHx4dHBsaGRgXFhUUExIREA8ODQwLCgkIBwYFBAMCAQAAIfkEAQAAAQAsAAAAAA0ADQAAAhSMj6lrwAjcC1GyahV+dcZJgeIIFgA7'; 131 132/** 133 * Sets the default font size. 134 */ 135Sidebar.prototype.expandedImage = (!mxClient.IS_SVG) ? IMAGE_PATH + '/expanded.gif' : 'data:image/gif;base64,R0lGODlhDQANAIABAJmZmf///yH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IE1hY2ludG9zaCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxREY3NzBERjZGNUYxMUU1QjZEOThCNDYxMDQ2MzNCQiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxREY3NzBFMDZGNUYxMUU1QjZEOThCNDYxMDQ2MzNCQiI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjFERjc3MERENkY1RjExRTVCNkQ5OEI0NjEwNDYzM0JCIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjFERjc3MERFNkY1RjExRTVCNkQ5OEI0NjEwNDYzM0JCIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+Af/+/fz7+vn49/b19PPy8fDv7u3s6+rp6Ofm5eTj4uHg397d3Nva2djX1tXU09LR0M/OzczLysnIx8bFxMPCwcC/vr28u7q5uLe2tbSzsrGwr66trKuqqainpqWko6KhoJ+enZybmpmYl5aVlJOSkZCPjo2Mi4qJiIeGhYSDgoGAf359fHt6eXh3dnV0c3JxcG9ubWxramloZ2ZlZGNiYWBfXl1cW1pZWFdWVVRTUlFQT05NTEtKSUhHRkVEQ0JBQD8+PTw7Ojk4NzY1NDMyMTAvLi0sKyopKCcmJSQjIiEgHx4dHBsaGRgXFhUUExIREA8ODQwLCgkIBwYFBAMCAQAAIfkEAQAAAQAsAAAAAA0ADQAAAhGMj6nL3QAjVHIu6azbvPtWAAA7'; 136 137/** 138 * 139 */ 140Sidebar.prototype.searchImage = (!mxClient.IS_SVG) ? IMAGE_PATH + '/search.png' : 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAEaSURBVHjabNGxS5VxFIfxz71XaWuQUJCG/gCHhgTD9VpEETg4aMOlQRp0EoezObgcd220KQiXmpretTAHQRBdojlQEJyukPdt+b1ywfvAGc7wnHP4nlZd1yKijQW8xzNc4Su+ZOYfQ3T6/f4YNvEJYzjELXp4VVXVz263+7cR2niBxAFeZ2YPi3iHR/gYERPDwhpOsd6sz8x/mfkNG3iOlWFhFj8y89J9KvzGXER0GuEaD42mgwHqUtoljbcRsTBCeINpfM/MgZLKPpaxFxGbOCqDXmILN7hoJrTKH+axhxmcYRxP0MIDnOBDZv5q1XUNIuJxifJp+UNV7t7BFM6xeic0RMQ4Bpl5W/ol7GISx/eEUUTECrbx+f8A8xhiZht9zsgAAAAASUVORK5CYII='; 141 142/** 143 * Specifies if tooltips should be visible. Default is true. 144 */ 145Sidebar.prototype.enableTooltips = true; 146 147/** 148 * Specifies the delay for the tooltip. Default is 16 px. 149 */ 150Sidebar.prototype.tooltipBorder = 16; 151 152/** 153 * Specifies the delay for the tooltip. Default is 300 ms. 154 */ 155Sidebar.prototype.tooltipDelay = 300; 156 157/** 158 * Specifies the delay for the drop target icons. Default is 200 ms. 159 */ 160Sidebar.prototype.dropTargetDelay = 200; 161 162/** 163 * Specifies the URL of the gear image. 164 */ 165Sidebar.prototype.gearImage = STENCIL_PATH + '/clipart/Gear_128x128.png'; 166 167/** 168 * Specifies the width of the thumbnails. 169 */ 170Sidebar.prototype.thumbWidth = 42; 171 172/** 173 * Specifies the height of the thumbnails. 174 */ 175Sidebar.prototype.thumbHeight = 42; 176 177/** 178 * Specifies the width of the thumbnails. 179 */ 180Sidebar.prototype.minThumbStrokeWidth = 1; 181 182/** 183 * Specifies the width of the thumbnails. 184 */ 185Sidebar.prototype.thumbAntiAlias = false; 186 187/** 188 * Specifies the padding for the thumbnails. Default is 3. 189 */ 190Sidebar.prototype.thumbPadding = (document.documentMode >= 5) ? 2 : 3; 191 192/** 193 * Specifies the delay for the tooltip. Default is 2 px. 194 */ 195Sidebar.prototype.thumbBorder = 2; 196 197/* 198 * Experimental smaller sidebar entries 199 */ 200if (urlParams['sidebar-entries'] != 'large') 201{ 202 Sidebar.prototype.thumbPadding = (document.documentMode >= 5) ? 0 : 1; 203 Sidebar.prototype.thumbBorder = 1; 204 Sidebar.prototype.thumbWidth = 32; 205 Sidebar.prototype.thumbHeight = 30; 206 Sidebar.prototype.minThumbStrokeWidth = 1.3; 207 Sidebar.prototype.thumbAntiAlias = true; 208} 209 210/** 211 * Specifies the size of the sidebar titles. 212 */ 213Sidebar.prototype.sidebarTitleSize = 8; 214 215/** 216 * Specifies if titles in the sidebar should be enabled. 217 */ 218Sidebar.prototype.sidebarTitles = false; 219 220/** 221 * Specifies if titles in the tooltips should be enabled. 222 */ 223Sidebar.prototype.tooltipTitles = true; 224 225/** 226 * Specifies if titles in the tooltips should be enabled. 227 */ 228Sidebar.prototype.maxTooltipWidth = 400; 229 230/** 231 * Specifies if titles in the tooltips should be enabled. 232 */ 233Sidebar.prototype.maxTooltipHeight = 400; 234 235/** 236 * Specifies if stencil files should be loaded and added to the search index 237 * when stencil palettes are added. If this is false then the stencil files 238 * are lazy-loaded when the palette is shown. 239 */ 240Sidebar.prototype.addStencilsToIndex = true; 241 242/** 243 * Specifies the width for clipart images. Default is 80. 244 */ 245Sidebar.prototype.defaultImageWidth = 80; 246 247/** 248 * Specifies the height for clipart images. Default is 80. 249 */ 250Sidebar.prototype.defaultImageHeight = 80; 251 252/** 253 * Specifies the height for clipart images. Default is 80. 254 */ 255Sidebar.prototype.tooltipMouseDown = null; 256 257/** 258 * Adds all palettes to the sidebar. 259 */ 260Sidebar.prototype.getTooltipOffset = function(elt, bounds) 261{ 262 var b = document.body; 263 var d = document.documentElement; 264 var bottom = Math.max(b.clientHeight || 0, d.clientHeight); 265 var width = bounds.width + 2 * this.tooltipBorder + 4; 266 var height = bounds.height + 2 * this.tooltipBorder; 267 268 return new mxPoint(this.container.offsetWidth + this.editorUi.splitSize + 10 + this.editorUi.container.offsetLeft, 269 Math.min(bottom - height - 20 /*status bar*/, Math.max(0, (this.editorUi.container.offsetTop + 270 this.container.offsetTop + elt.offsetTop - this.container.scrollTop - height / 2 + 16)))); 271}; 272 273/** 274 * Adds all palettes to the sidebar. 275 */ 276Sidebar.prototype.createTooltip = function(elt, cells, w, h, title, showLabel, off, maxSize, mouseDown, closable, applyAllStyles) 277{ 278 applyAllStyles = (applyAllStyles != null) ? applyAllStyles : true; 279 this.tooltipMouseDown = mouseDown; 280 281 // Lazy creation of the DOM nodes and graph instance 282 if (this.tooltip == null) 283 { 284 this.tooltip = document.createElement('div'); 285 this.tooltip.className = 'geSidebarTooltip'; 286 this.tooltip.style.userSelect = 'none'; 287 this.tooltip.style.zIndex = mxPopupMenu.prototype.zIndex - 1; 288 document.body.appendChild(this.tooltip); 289 290 mxEvent.addMouseWheelListener(mxUtils.bind(this, function(evt) 291 { 292 this.hideTooltip(); 293 }), this.tooltip); 294 295 this.graph2 = new Graph(this.tooltip, null, null, this.editorUi.editor.graph.getStylesheet()); 296 this.graph2.resetViewOnRootChange = false; 297 this.graph2.foldingEnabled = false; 298 this.graph2.gridEnabled = false; 299 this.graph2.autoScroll = false; 300 this.graph2.setTooltips(false); 301 this.graph2.setConnectable(false); 302 this.graph2.setPanning(false); 303 this.graph2.setEnabled(false); 304 305 // Blocks all links 306 this.graph2.openLink = mxUtils.bind(this, function() 307 { 308 this.hideTooltip(); 309 }); 310 311 mxEvent.addGestureListeners(this.tooltip, mxUtils.bind(this, function(evt) 312 { 313 if (this.tooltipMouseDown != null) 314 { 315 this.tooltipMouseDown(evt); 316 } 317 318 window.setTimeout(mxUtils.bind(this, function() 319 { 320 if (this.tooltipCloseImage == null || this.tooltipCloseImage.style.display == 'none') 321 { 322 this.hideTooltip(); 323 } 324 }), 0); 325 }), null, mxUtils.bind(this, function(evt) 326 { 327 this.hideTooltip(); 328 })); 329 330 if (!mxClient.IS_SVG) 331 { 332 this.graph2.view.canvas.style.position = 'relative'; 333 } 334 335 var close = document.createElement('img'); 336 close.setAttribute('src', Dialog.prototype.closeImage); 337 close.setAttribute('title', mxResources.get('close')); 338 close.style.position = 'absolute'; 339 close.style.cursor = 'default'; 340 close.style.padding = '8px'; 341 close.style.right = '2px'; 342 close.style.top = '2px'; 343 this.tooltip.appendChild(close); 344 this.tooltipCloseImage = close; 345 346 mxEvent.addListener(close, 'click', mxUtils.bind(this, function(evt) 347 { 348 this.hideTooltip(); 349 mxEvent.consume(evt); 350 })); 351 } 352 353 this.tooltipCloseImage.style.display = (closable) ? '' : 'none'; 354 this.graph2.model.clear(); 355 this.graph2.view.setTranslate(this.tooltipBorder, this.tooltipBorder); 356 357 if (!maxSize && (w > this.maxTooltipWidth || h > this.maxTooltipHeight)) 358 { 359 this.graph2.view.scale = Math.round(Math.min(this.maxTooltipWidth / w, this.maxTooltipHeight / h) * 100) / 100; 360 } 361 else 362 { 363 this.graph2.view.scale = 1; 364 } 365 366 this.tooltip.style.display = 'block'; 367 this.graph2.labelsVisible = (showLabel == null || showLabel); 368 var fo = mxClient.NO_FO; 369 mxClient.NO_FO = Editor.prototype.originalNoForeignObject; 370 371 // Applies current style for preview 372 var temp = this.graph2.cloneCells(cells); 373 this.editorUi.insertHandler(temp, null, this.graph2.model, 374 (!applyAllStyles) ? this.editorUi.editor.graph.defaultVertexStyle : null, 375 (!applyAllStyles) ? this.editorUi.editor.graph.defaultEdgeStyle : null, 376 applyAllStyles, true); 377 this.graph2.addCells(temp); 378 379 mxClient.NO_FO = fo; 380 var bounds = this.graph2.getGraphBounds(); 381 382 // Maximum size applied with transform for faster repaint 383 if (maxSize && w > 0 && h > 0 && (bounds.width > w || bounds.height > h)) 384 { 385 var s = Math.round(Math.min(w / bounds.width, h / bounds.height) * 100) / 100; 386 387 if (!mxClient.NO_FO) 388 { 389 this.graph2.view.getDrawPane().ownerSVGElement.style.transform = 'scale(' + s + ')'; 390 this.graph2.view.getDrawPane().ownerSVGElement.style.transformOrigin = '0 0'; 391 bounds.width *= s; 392 bounds.height *= s; 393 } 394 else 395 { 396 this.graph2.view.setScale(Math.round(Math.min(this.maxTooltipWidth / bounds.width, this.maxTooltipHeight / bounds.height) * 100) / 100); 397 bounds = this.graph2.getGraphBounds(); 398 } 399 } 400 else if (!mxClient.NO_FO) 401 { 402 this.graph2.view.getDrawPane().ownerSVGElement.style.transform = ''; 403 } 404 405 var width = bounds.width + 2 * this.tooltipBorder + 4; 406 var height = bounds.height + 2 * this.tooltipBorder; 407 408 this.tooltip.style.overflow = 'visible'; 409 this.tooltip.style.width = width + 'px'; 410 var w2 = width; 411 412 // Adds title for entry 413 if (this.tooltipTitles && title != null && title.length > 0) 414 { 415 if (this.tooltipTitle == null) 416 { 417 this.tooltipTitle = document.createElement('div'); 418 this.tooltipTitle.style.borderTop = '1px solid gray'; 419 this.tooltipTitle.style.textAlign = 'center'; 420 this.tooltipTitle.style.width = '100%'; 421 this.tooltipTitle.style.overflow = 'hidden'; 422 this.tooltipTitle.style.position = 'absolute'; 423 this.tooltipTitle.style.paddingTop = '6px'; 424 this.tooltipTitle.style.bottom = '6px'; 425 426 this.tooltip.appendChild(this.tooltipTitle); 427 } 428 else 429 { 430 this.tooltipTitle.innerHTML = ''; 431 } 432 433 this.tooltipTitle.style.display = ''; 434 mxUtils.write(this.tooltipTitle, title); 435 436 // Allows for wider labels 437 w2 = Math.min(this.maxTooltipWidth, Math.max(width, this.tooltipTitle.scrollWidth + 4)); 438 var ddy = this.tooltipTitle.offsetHeight + 10; 439 height += ddy; 440 441 if (mxClient.IS_SVG) 442 { 443 this.tooltipTitle.style.marginTop = (2 - ddy) + 'px'; 444 } 445 else 446 { 447 height -= 6; 448 this.tooltipTitle.style.top = (height - ddy) + 'px'; 449 } 450 } 451 else if (this.tooltipTitle != null && this.tooltipTitle.parentNode != null) 452 { 453 this.tooltipTitle.style.display = 'none'; 454 } 455 456 // Updates width if label is wider 457 if (w2 > width) 458 { 459 this.tooltip.style.width = w2 + 'px'; 460 } 461 462 this.tooltip.style.height = height + 'px'; 463 var x0 = -Math.round(bounds.x - this.tooltipBorder) + 464 ((w2 > width) ? (w2 - width) / 2 : 0); 465 var y0 = -Math.round(bounds.y - this.tooltipBorder); 466 off = (off != null) ? off : this.getTooltipOffset(elt, bounds); 467 var left = off.x; 468 var top = off.y; 469 470 if (mxClient.IS_SVG) 471 { 472 if (x0 != 0 || y0 != 0) 473 { 474 this.graph2.view.canvas.setAttribute('transform', 'translate(' + x0 + ',' + y0 + ')'); 475 } 476 else 477 { 478 this.graph2.view.canvas.removeAttribute('transform'); 479 } 480 } 481 else 482 { 483 this.graph2.view.drawPane.style.left = x0 + 'px'; 484 this.graph2.view.drawPane.style.top = y0 + 'px'; 485 } 486 487 // Workaround for ignored position CSS style in IE9 488 // (changes to relative without the following line) 489 this.tooltip.style.position = 'absolute'; 490 this.tooltip.style.left = left + 'px'; 491 this.tooltip.style.top = top + 'px'; 492 493 mxUtils.fit(this.tooltip); 494 this.lastCreated = Date.now(); 495}; 496 497/** 498 * Adds all palettes to the sidebar. 499 */ 500Sidebar.prototype.showTooltip = function(elt, cells, w, h, title, showLabel) 501{ 502 if (this.enableTooltips && this.showTooltips) 503 { 504 if (this.currentElt != elt) 505 { 506 if (this.thread != null) 507 { 508 window.clearTimeout(this.thread); 509 this.thread = null; 510 } 511 512 var show = mxUtils.bind(this, function() 513 { 514 this.createTooltip(elt, cells, w, h, title, showLabel); 515 }); 516 517 if (this.tooltip != null && this.tooltip.style.display != 'none') 518 { 519 show(); 520 } 521 else 522 { 523 this.thread = window.setTimeout(show, this.tooltipDelay); 524 } 525 526 this.currentElt = elt; 527 } 528 } 529}; 530 531/** 532 * Hides the current tooltip. 533 */ 534Sidebar.prototype.hideTooltip = function() 535{ 536 if (this.thread != null) 537 { 538 window.clearTimeout(this.thread); 539 this.thread = null; 540 } 541 542 if (this.tooltip != null) 543 { 544 this.tooltip.style.display = 'none'; 545 this.currentElt = null; 546 } 547 548 this.tooltipMouseDown = null; 549}; 550 551/** 552 * Hides the current tooltip. 553 */ 554Sidebar.prototype.addDataEntry = function(tags, width, height, title, data) 555{ 556 return this.addEntry(tags, mxUtils.bind(this, function() 557 { 558 return this.createVertexTemplateFromData(data, width, height, title); 559 })); 560}; 561 562/** 563 * Adds the give entries to the search index. 564 */ 565Sidebar.prototype.addEntries = function(images) 566{ 567 for (var i = 0; i < images.length; i++) 568 { 569 (mxUtils.bind(this, function(img) 570 { 571 var data = img.data; 572 var tags = (img.title != null) ? img.title : ''; 573 574 if (img.tags != null) 575 { 576 tags += ' ' + img.tags; 577 } 578 579 if (data != null && tags.length > 0) 580 { 581 this.addEntry(tags, mxUtils.bind(this, function() 582 { 583 data = this.editorUi.convertDataUri(data); 584 var s = 'shape=image;verticalLabelPosition=bottom;verticalAlign=top;imageAspect=0;'; 585 586 if (img.aspect == 'fixed') 587 { 588 s += 'aspect=fixed;' 589 } 590 591 return this.createVertexTemplate(s + 'image=' + 592 data, img.w, img.h, '', img.title || '', false, false, true) 593 })); 594 } 595 else if (img.xml != null && tags.length > 0) 596 { 597 this.addEntry(tags, mxUtils.bind(this, function() 598 { 599 var cells = this.editorUi.stringToCells(Graph.decompress(img.xml)); 600 601 return this.createVertexTemplateFromCells( 602 cells, img.w, img.h, img.title || '', true, false, true); 603 })); 604 } 605 }))(images[i]); 606 } 607}; 608 609/** 610 * Hides the current tooltip. 611 */ 612Sidebar.prototype.setCurrentSearchEntryLibrary = function(id, lib) 613{ 614 this.currentSearchEntryLibrary = (id != null) ? {id: id, lib: lib} : null; 615}; 616 617/** 618 * Hides the current tooltip. 619 */ 620Sidebar.prototype.addEntry = function(tags, fn) 621{ 622 if (this.taglist != null && tags != null && tags.length > 0) 623 { 624 if (this.currentSearchEntryLibrary != null) 625 { 626 fn.parentLibraries = [this.currentSearchEntryLibrary]; 627 } 628 629 // Replaces special characters 630 var tmp = tags.toLowerCase().replace(/[\/\,\(\)]/g, ' ').split(' '); 631 var tagList = []; 632 var hash = {}; 633 634 // Finds unique tags 635 for (var i = 0; i < tmp.length; i++) 636 { 637 if (hash[tmp[i]] == null) 638 { 639 hash[tmp[i]] = true; 640 tagList.push(tmp[i]); 641 } 642 643 // Adds additional entry with removed trailing numbers 644 var normalized = tmp[i].replace(/\.*\d*$/, ''); 645 646 if (normalized != tmp[i]) 647 { 648 if (hash[normalized] == null) 649 { 650 hash[normalized] = true; 651 tagList.push(normalized); 652 } 653 } 654 } 655 656 for (var i = 0; i < tagList.length; i++) 657 { 658 this.addEntryForTag(tagList[i], fn); 659 } 660 } 661 662 return fn; 663}; 664 665/** 666 * Hides the current tooltip. 667 */ 668Sidebar.prototype.addEntryForTag = function(tag, fn) 669{ 670 if (tag != null && tag.length > 1) 671 { 672 var entry = this.taglist[tag]; 673 674 if (typeof entry !== 'object') 675 { 676 entry = {entries: []}; 677 this.taglist[tag] = entry; 678 } 679 680 entry.entries.push(fn); 681 } 682}; 683 684/** 685 * Adds shape search UI. 686 */ 687Sidebar.prototype.searchEntries = function(searchTerms, count, page, success, error) 688{ 689 if (this.taglist != null && searchTerms != null) 690 { 691 var tmp = searchTerms.toLowerCase().split(' '); 692 var dict = new mxDictionary(); 693 var max = (page + 1) * count; 694 var results = []; 695 var index = 0; 696 697 for (var i = 0; i < tmp.length; i++) 698 { 699 if (tmp[i].length > 0) 700 { 701 var entry = this.taglist[tmp[i]]; 702 var tmpDict = new mxDictionary(); 703 704 if (entry != null) 705 { 706 var arr = entry.entries; 707 results = []; 708 709 for (var j = 0; j < arr.length; j++) 710 { 711 var entry = arr[j]; 712 713 // NOTE Array does not contain duplicates 714 if ((index == 0) == (dict.get(entry) == null)) 715 { 716 tmpDict.put(entry, entry); 717 results.push(entry); 718 719 if (i == tmp.length - 1 && results.length == max) 720 { 721 success(results.slice(page * count, max), max, true, tmp); 722 723 return; 724 } 725 } 726 } 727 } 728 else 729 { 730 results = []; 731 } 732 733 dict = tmpDict; 734 index++; 735 } 736 } 737 738 var len = results.length; 739 success(results.slice(page * count, (page + 1) * count), len, false, tmp); 740 } 741 else 742 { 743 success([], null, null, tmp); 744 } 745}; 746 747/** 748 * Adds shape search UI. 749 */ 750Sidebar.prototype.filterTags = function(tags) 751{ 752 if (tags != null) 753 { 754 var arr = tags.split(' '); 755 var result = []; 756 var hash = {}; 757 758 // Ignores tags with leading numbers, strips trailing numbers 759 for (var i = 0; i < arr.length; i++) 760 { 761 // Removes duplicates 762 if (hash[arr[i]] == null) 763 { 764 hash[arr[i]] = '1'; 765 result.push(arr[i]); 766 } 767 } 768 769 return result.join(' '); 770 } 771 772 return null; 773}; 774 775/** 776 * Adds the general palette to the sidebar. 777 */ 778Sidebar.prototype.cloneCell = function(cell, value) 779{ 780 var clone = cell.clone(); 781 782 if (value != null) 783 { 784 clone.value = value; 785 } 786 787 return clone; 788}; 789 790/** 791 * Adds shape search UI. 792 */ 793Sidebar.prototype.showPopupMenuForEntry = function(elt, libs, evt) 794{ 795 // Hook for subclassers 796}; 797 798/** 799 * Adds shape search UI. 800 */ 801Sidebar.prototype.addSearchPalette = function(expand) 802{ 803 var elt = document.createElement('div'); 804 elt.style.visibility = 'hidden'; 805 this.container.appendChild(elt); 806 807 var div = document.createElement('div'); 808 div.className = 'geSidebar'; 809 div.style.boxSizing = 'border-box'; 810 div.style.overflow = 'hidden'; 811 div.style.width = '100%'; 812 div.style.padding = '8px'; 813 div.style.paddingTop = '14px'; 814 div.style.paddingBottom = '0px'; 815 816 if (!expand) 817 { 818 div.style.display = 'none'; 819 } 820 821 var inner = document.createElement('div'); 822 inner.style.whiteSpace = 'nowrap'; 823 inner.style.textOverflow = 'clip'; 824 inner.style.paddingBottom = '8px'; 825 inner.style.cursor = 'default'; 826 827 var input = document.createElement('input'); 828 input.setAttribute('placeholder', mxResources.get('searchShapes')); 829 input.setAttribute('type', 'text'); 830 input.style.fontSize = '12px'; 831 input.style.overflow = 'hidden'; 832 input.style.boxSizing = 'border-box'; 833 input.style.border = 'solid 1px #d5d5d5'; 834 input.style.borderRadius = '4px'; 835 input.style.width = '100%'; 836 input.style.outline = 'none'; 837 input.style.padding = '6px'; 838 input.style.paddingRight = '20px'; 839 inner.appendChild(input); 840 841 var cross = document.createElement('img'); 842 cross.setAttribute('src', Sidebar.prototype.searchImage); 843 cross.setAttribute('title', mxResources.get('search')); 844 cross.style.position = 'relative'; 845 cross.style.left = '-18px'; 846 cross.style.top = '1px'; 847 848 // Needed to block event transparency in IE 849 cross.style.background = 'url(\'' + this.editorUi.editor.transparentImage + '\')'; 850 851 var find; 852 853 inner.appendChild(cross); 854 div.appendChild(inner); 855 856 var center = document.createElement('center'); 857 var button = mxUtils.button(mxResources.get('moreResults'), function() 858 { 859 find(); 860 }); 861 button.style.display = 'none'; 862 863 // Workaround for inherited line-height in quirks mode 864 button.style.lineHeight = 'normal'; 865 button.style.fontSize = '12px'; 866 button.style.padding = '6px 12px 6px 12px'; 867 button.style.marginTop = '4px'; 868 button.style.marginBottom = '8px'; 869 center.style.paddingTop = '4px'; 870 center.style.paddingBottom = '4px'; 871 872 center.appendChild(button); 873 div.appendChild(center); 874 875 var searchTerm = ''; 876 var active = false; 877 var complete = false; 878 var page = 0; 879 var hash = new Object(); 880 881 // Count is dynamically updated below 882 var count = 12; 883 884 var clearDiv = mxUtils.bind(this, function() 885 { 886 active = false; 887 this.currentSearch = null; 888 var child = div.firstChild; 889 890 while (child != null) 891 { 892 var next = child.nextSibling; 893 894 if (child != inner && child != center) 895 { 896 child.parentNode.removeChild(child); 897 } 898 899 child = next; 900 } 901 }); 902 903 mxEvent.addListener(cross, 'click', function() 904 { 905 if (cross.getAttribute('src') == Dialog.prototype.closeImage) 906 { 907 cross.setAttribute('src', Sidebar.prototype.searchImage); 908 cross.setAttribute('title', mxResources.get('search')); 909 button.style.display = 'none'; 910 input.value = ''; 911 searchTerm = ''; 912 clearDiv(); 913 } 914 915 input.focus(); 916 }); 917 918 find = mxUtils.bind(this, function() 919 { 920 // Shows 4 rows (minimum 4 results) 921 count = 4 * Math.max(1, Math.floor(this.container.clientWidth / (this.thumbWidth + 10))); 922 this.hideTooltip(); 923 924 if (input.value != '') 925 { 926 if (center.parentNode != null) 927 { 928 if (searchTerm != input.value) 929 { 930 clearDiv(); 931 searchTerm = input.value; 932 hash = new Object(); 933 complete = false; 934 page = 0; 935 } 936 937 if (!active && !complete) 938 { 939 button.setAttribute('disabled', 'true'); 940 button.style.display = ''; 941 button.style.cursor = 'wait'; 942 button.innerHTML = mxResources.get('loading') + '...'; 943 active = true; 944 945 // Ignores old results 946 var current = new Object(); 947 this.currentSearch = current; 948 949 this.searchEntries(searchTerm, count, page, mxUtils.bind(this, function(results, len, more, terms) 950 { 951 if (this.currentSearch == current) 952 { 953 results = (results != null) ? results : []; 954 active = false; 955 page++; 956 this.insertSearchHint(div, searchTerm, count, page, results, len, more, terms); 957 958 // Allows to repeat the search 959 if (results.length == 0 && page == 1) 960 { 961 searchTerm = ''; 962 } 963 964 if (center.parentNode != null) 965 { 966 center.parentNode.removeChild(center); 967 } 968 969 for (var i = 0; i < results.length; i++) 970 { 971 (mxUtils.bind(this, function(result) 972 { 973 try 974 { 975 var elt = result(); 976 977 // Avoids duplicates in results 978 if (hash[elt.innerHTML] == null) 979 { 980 hash[elt.innerHTML] = (result.parentLibraries != null) ? result.parentLibraries.slice() : []; 981 div.appendChild(elt); 982 } 983 else if (result.parentLibraries != null) 984 { 985 hash[elt.innerHTML] = hash[elt.innerHTML].concat(result.parentLibraries); 986 } 987 988 mxEvent.addGestureListeners(elt, null, null, mxUtils.bind(this, function(evt) 989 { 990 var libs = hash[elt.innerHTML]; 991 992 if (mxEvent.isPopupTrigger(evt)) 993 { 994 this.showPopupMenuForEntry(elt, libs, evt); 995 } 996 })); 997 998 // Disables the built-in context menu 999 mxEvent.disableContextMenu(elt); 1000 } 1001 catch (e) 1002 { 1003 // ignore 1004 } 1005 }))(results[i]); 1006 } 1007 1008 if (more) 1009 { 1010 button.removeAttribute('disabled'); 1011 button.innerHTML = mxResources.get('moreResults'); 1012 } 1013 else 1014 { 1015 button.innerHTML = mxResources.get('reset'); 1016 button.style.display = 'none'; 1017 complete = true; 1018 } 1019 1020 button.style.cursor = ''; 1021 div.appendChild(center); 1022 } 1023 }), mxUtils.bind(this, function() 1024 { 1025 // TODO: Error handling 1026 button.style.cursor = ''; 1027 })); 1028 } 1029 } 1030 } 1031 else 1032 { 1033 clearDiv(); 1034 input.value = ''; 1035 searchTerm = ''; 1036 hash = new Object(); 1037 button.style.display = 'none'; 1038 complete = false; 1039 input.focus(); 1040 } 1041 }); 1042 1043 this.searchShapes = function(value) 1044 { 1045 input.value = value; 1046 find(); 1047 }; 1048 1049 mxEvent.addListener(input, 'keydown', mxUtils.bind(this, function(evt) 1050 { 1051 if (evt.keyCode == 13 /* Enter */) 1052 { 1053 find(); 1054 mxEvent.consume(evt); 1055 } 1056 })); 1057 1058 mxEvent.addListener(input, 'keyup', mxUtils.bind(this, function(evt) 1059 { 1060 if (input.value == '') 1061 { 1062 cross.setAttribute('src', Sidebar.prototype.searchImage); 1063 cross.setAttribute('title', mxResources.get('search')); 1064 } 1065 else 1066 { 1067 cross.setAttribute('src', Dialog.prototype.closeImage); 1068 cross.setAttribute('title', mxResources.get('reset')); 1069 } 1070 1071 if (input.value == '') 1072 { 1073 complete = true; 1074 button.style.display = 'none'; 1075 } 1076 else if (input.value != searchTerm) 1077 { 1078 button.style.display = 'none'; 1079 complete = false; 1080 } 1081 else if (!active) 1082 { 1083 if (complete) 1084 { 1085 button.style.display = 'none'; 1086 } 1087 else 1088 { 1089 button.style.display = ''; 1090 } 1091 } 1092 })); 1093 1094 // Workaround for blocked text selection in Editor 1095 mxEvent.addListener(input, 'mousedown', function(evt) 1096 { 1097 if (evt.stopPropagation) 1098 { 1099 evt.stopPropagation(); 1100 } 1101 1102 evt.cancelBubble = true; 1103 }); 1104 1105 // Workaround for blocked text selection in Editor 1106 mxEvent.addListener(input, 'selectstart', function(evt) 1107 { 1108 if (evt.stopPropagation) 1109 { 1110 evt.stopPropagation(); 1111 } 1112 1113 evt.cancelBubble = true; 1114 }); 1115 1116 var outer = document.createElement('div'); 1117 outer.appendChild(div); 1118 this.container.appendChild(outer); 1119 1120 // Keeps references to the DOM nodes 1121 this.palettes['search'] = [elt, outer]; 1122}; 1123 1124/** 1125 * Adds the general palette to the sidebar. 1126 */ 1127Sidebar.prototype.insertSearchHint = function(div, searchTerm, count, page, results, len, more, terms) 1128{ 1129 if (results.length == 0 && page == 1) 1130 { 1131 var err = document.createElement('div'); 1132 err.className = 'geTitle'; 1133 err.style.cssText = 'background-color:transparent;border-color:transparent;' + 1134 'color:gray;padding:6px 0px 0px 0px !important;margin:4px 8px 4px 8px;' + 1135 'text-align:center;cursor:default !important'; 1136 1137 mxUtils.write(err, mxResources.get('noResultsFor', [searchTerm])); 1138 div.appendChild(err); 1139 } 1140}; 1141 1142/** 1143 * Adds the general palette to the sidebar. 1144 */ 1145Sidebar.prototype.addGeneralPalette = function(expand) 1146{ 1147 var lineTags = 'line lines connector connectors connection connections arrow arrows '; 1148 this.setCurrentSearchEntryLibrary('general', 'general'); 1149 var sb = this; 1150 1151 var temp = parseInt(this.editorUi.editor.graph.defaultVertexStyle['fontSize']); 1152 var fontSize = !isNaN(temp) ? 'fontSize=' + Math.min(16, temp) + ';' : ''; 1153 1154 // Reusable cells 1155 var field = new mxCell('List Item', new mxGeometry(0, 0, 80, 30), 1156 'text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;' + 1157 'spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];' + 1158 'portConstraint=eastwest;rotatable=0;' + fontSize); 1159 field.vertex = true; 1160 1161 var fns = [ 1162 this.createVertexTemplateEntry('rounded=0;whiteSpace=wrap;html=1;', 120, 60, '', 'Rectangle', null, null, 'rect rectangle box'), 1163 this.createVertexTemplateEntry('rounded=1;whiteSpace=wrap;html=1;', 120, 60, '', 'Rounded Rectangle', null, null, 'rounded rect rectangle box'), 1164 // Explicit strokecolor/fillcolor=none is a workaround to maintain transparent background regardless of current style 1165 this.createVertexTemplateEntry('text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;', 1166 60, 30, 'Text', 'Text', null, null, 'text textbox textarea label'), 1167 this.createVertexTemplateEntry('text;html=1;strokeColor=none;fillColor=none;spacing=5;spacingTop=-20;whiteSpace=wrap;overflow=hidden;rounded=0;', 190, 120, 1168 '<h1>Heading</h1><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>', 1169 'Textbox', null, null, 'text textbox textarea'), 1170 this.createVertexTemplateEntry('ellipse;whiteSpace=wrap;html=1;', 120, 80, '', 'Ellipse', null, null, 'oval ellipse state'), 1171 this.createVertexTemplateEntry('whiteSpace=wrap;html=1;aspect=fixed;', 80, 80, '', 'Square', null, null, 'square'), 1172 this.createVertexTemplateEntry('ellipse;whiteSpace=wrap;html=1;aspect=fixed;', 80, 80, '', 'Circle', null, null, 'circle'), 1173 this.createVertexTemplateEntry('shape=process;whiteSpace=wrap;html=1;backgroundOutline=1;', 120, 60, '', 'Process', null, null, 'process task'), 1174 this.createVertexTemplateEntry('rhombus;whiteSpace=wrap;html=1;', 80, 80, '', 'Diamond', null, null, 'diamond rhombus if condition decision conditional question test'), 1175 this.createVertexTemplateEntry('shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;', 120, 60, '', 'Parallelogram'), 1176 this.createVertexTemplateEntry('shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;', 120, 80, '', 'Hexagon', null, null, 'hexagon preparation'), 1177 this.createVertexTemplateEntry('triangle;whiteSpace=wrap;html=1;', 60, 80, '', 'Triangle', null, null, 'triangle logic inverter buffer'), 1178 this.createVertexTemplateEntry('shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;', 60, 80, '', 'Cylinder', null, null, 'cylinder data database'), 1179 this.createVertexTemplateEntry('ellipse;shape=cloud;whiteSpace=wrap;html=1;', 120, 80, '', 'Cloud', null, null, 'cloud network'), 1180 this.createVertexTemplateEntry('shape=document;whiteSpace=wrap;html=1;boundedLbl=1;', 120, 80, '', 'Document'), 1181 this.createVertexTemplateEntry('shape=internalStorage;whiteSpace=wrap;html=1;backgroundOutline=1;', 80, 80, '', 'Internal Storage'), 1182 this.createVertexTemplateEntry('shape=cube;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;darkOpacity=0.05;darkOpacity2=0.1;', 120, 80, '', 'Cube'), 1183 this.createVertexTemplateEntry('shape=step;perimeter=stepPerimeter;whiteSpace=wrap;html=1;fixedSize=1;', 120, 80, '', 'Step'), 1184 this.createVertexTemplateEntry('shape=trapezoid;perimeter=trapezoidPerimeter;whiteSpace=wrap;html=1;fixedSize=1;', 120, 60, '', 'Trapezoid'), 1185 this.createVertexTemplateEntry('shape=tape;whiteSpace=wrap;html=1;', 120, 100, '', 'Tape'), 1186 this.createVertexTemplateEntry('shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;', 80, 100, '', 'Note'), 1187 this.createVertexTemplateEntry('shape=card;whiteSpace=wrap;html=1;', 80, 100, '', 'Card'), 1188 this.createVertexTemplateEntry('shape=callout;whiteSpace=wrap;html=1;perimeter=calloutPerimeter;', 120, 80, '', 'Callout', null, null, 'bubble chat thought speech message'), 1189 this.createVertexTemplateEntry('shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;', 30, 60, 'Actor', 'Actor', false, null, 'user person human stickman'), 1190 this.createVertexTemplateEntry('shape=xor;whiteSpace=wrap;html=1;', 60, 80, '', 'Or', null, null, 'logic or'), 1191 this.createVertexTemplateEntry('shape=or;whiteSpace=wrap;html=1;', 60, 80, '', 'And', null, null, 'logic and'), 1192 this.createVertexTemplateEntry('shape=dataStorage;whiteSpace=wrap;html=1;fixedSize=1;', 100, 80, '', 'Data Storage'), 1193 this.createVertexTemplateEntry('swimlane;startSize=0;', 200, 200, '', 'Container', null, null, 'container swimlane lane pool group'), 1194 this.createVertexTemplateEntry('swimlane;', 200, 200, 'Vertical Container', 'Container', null, null, 'container swimlane lane pool group'), 1195 this.createVertexTemplateEntry('swimlane;horizontal=0;', 200, 200, 'Horizontal Container', 'Horizontal Container', null, null, 'container swimlane lane pool group'), 1196 this.addEntry('list group erd table', function() 1197 { 1198 var cell = new mxCell('List', new mxGeometry(0, 0, 140, 120), 1199 'swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;' + 1200 'resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;'); 1201 cell.vertex = true; 1202 cell.insert(sb.cloneCell(field, 'Item 1')); 1203 cell.insert(sb.cloneCell(field, 'Item 2')); 1204 cell.insert(sb.cloneCell(field, 'Item 3')); 1205 1206 return sb.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, 'List'); 1207 }), 1208 this.addEntry('list item entry value group erd table', function() 1209 { 1210 return sb.createVertexTemplateFromCells([sb.cloneCell(field, 'List Item')], field.geometry.width, field.geometry.height, 'List Item'); 1211 }), 1212 this.addEntry('curve', mxUtils.bind(this, function() 1213 { 1214 var cell = new mxCell('', new mxGeometry(0, 0, 50, 50), 'curved=1;endArrow=classic;html=1;'); 1215 cell.geometry.setTerminalPoint(new mxPoint(0, 50), true); 1216 cell.geometry.setTerminalPoint(new mxPoint(50, 0), false); 1217 cell.geometry.points = [new mxPoint(50, 50), new mxPoint(0, 0)]; 1218 cell.geometry.relative = true; 1219 cell.edge = true; 1220 1221 return this.createEdgeTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, 'Curve'); 1222 })), 1223 this.createEdgeTemplateEntry('shape=flexArrow;endArrow=classic;startArrow=classic;html=1;', 100, 100, '', 'Bidirectional Arrow', null, lineTags + 'bidirectional'), 1224 this.createEdgeTemplateEntry('shape=flexArrow;endArrow=classic;html=1;', 50, 50, '', 'Arrow', null, lineTags + 'directional directed'), 1225 this.createEdgeTemplateEntry('endArrow=none;dashed=1;html=1;', 50, 50, '', 'Dashed Line', null, lineTags + 'dashed undirected no'), 1226 this.createEdgeTemplateEntry('endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=2;', 50, 50, '', 'Dotted Line', null, lineTags + 'dotted undirected no'), 1227 this.createEdgeTemplateEntry('endArrow=none;html=1;', 50, 50, '', 'Line', null, lineTags + 'simple undirected plain blank no'), 1228 this.createEdgeTemplateEntry('endArrow=classic;startArrow=classic;html=1;', 50, 50, '', 'Bidirectional Connector', null, lineTags + 'bidirectional'), 1229 this.createEdgeTemplateEntry('endArrow=classic;html=1;', 50, 50, '', 'Directional Connector', null, lineTags + 'directional directed'), 1230 this.createEdgeTemplateEntry('shape=link;html=1;', 100, 0, '', 'Link', null, lineTags + 'link'), 1231 this.addEntry(lineTags + 'edge title', mxUtils.bind(this, function() 1232 { 1233 var edge = new mxCell('', new mxGeometry(0, 0, 0, 0), 'endArrow=classic;html=1;'); 1234 edge.geometry.setTerminalPoint(new mxPoint(0, 0), true); 1235 edge.geometry.setTerminalPoint(new mxPoint(100, 0), false); 1236 edge.geometry.relative = true; 1237 edge.edge = true; 1238 1239 var cell0 = new mxCell('Label', new mxGeometry(0, 0, 0, 0), 'edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;'); 1240 cell0.geometry.relative = true; 1241 cell0.setConnectable(false); 1242 cell0.vertex = true; 1243 edge.insert(cell0); 1244 1245 return this.createEdgeTemplateFromCells([edge], 100, 0, 'Connector with Label'); 1246 })), 1247 this.addEntry(lineTags + 'edge title multiplicity', mxUtils.bind(this, function() 1248 { 1249 var edge = new mxCell('', new mxGeometry(0, 0, 0, 0), 'endArrow=classic;html=1;'); 1250 edge.geometry.setTerminalPoint(new mxPoint(0, 0), true); 1251 edge.geometry.setTerminalPoint(new mxPoint(160, 0), false); 1252 edge.geometry.relative = true; 1253 edge.edge = true; 1254 1255 var cell0 = new mxCell('Label', new mxGeometry(0, 0, 0, 0), 'edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;'); 1256 cell0.geometry.relative = true; 1257 cell0.setConnectable(false); 1258 cell0.vertex = true; 1259 edge.insert(cell0); 1260 1261 var cell1 = new mxCell('Source', new mxGeometry(-1, 0, 0, 0), 'edgeLabel;resizable=0;html=1;align=left;verticalAlign=bottom;'); 1262 cell1.geometry.relative = true; 1263 cell1.setConnectable(false); 1264 cell1.vertex = true; 1265 edge.insert(cell1); 1266 1267 return this.createEdgeTemplateFromCells([edge], 160, 0, 'Connector with 2 Labels'); 1268 })), 1269 this.addEntry(lineTags + 'edge title multiplicity', mxUtils.bind(this, function() 1270 { 1271 var edge = new mxCell('', new mxGeometry(0, 0, 0, 0), 'endArrow=classic;html=1;'); 1272 edge.geometry.setTerminalPoint(new mxPoint(0, 0), true); 1273 edge.geometry.setTerminalPoint(new mxPoint(160, 0), false); 1274 edge.geometry.relative = true; 1275 edge.edge = true; 1276 1277 var cell0 = new mxCell('Label', new mxGeometry(0, 0, 0, 0), 'edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;'); 1278 cell0.geometry.relative = true; 1279 cell0.setConnectable(false); 1280 cell0.vertex = true; 1281 edge.insert(cell0); 1282 1283 var cell1 = new mxCell('Source', new mxGeometry(-1, 0, 0, 0), 'edgeLabel;resizable=0;html=1;align=left;verticalAlign=bottom;'); 1284 cell1.geometry.relative = true; 1285 cell1.setConnectable(false); 1286 cell1.vertex = true; 1287 edge.insert(cell1); 1288 1289 var cell2 = new mxCell('Target', new mxGeometry(1, 0, 0, 0), 'edgeLabel;resizable=0;html=1;align=right;verticalAlign=bottom;'); 1290 cell2.geometry.relative = true; 1291 cell2.setConnectable(false); 1292 cell2.vertex = true; 1293 edge.insert(cell2); 1294 1295 return this.createEdgeTemplateFromCells([edge], 160, 0, 'Connector with 3 Labels'); 1296 })), 1297 this.addEntry(lineTags + 'edge shape symbol message mail email', mxUtils.bind(this, function() 1298 { 1299 var edge = new mxCell('', new mxGeometry(0, 0, 0, 0), 'endArrow=classic;html=1;'); 1300 edge.geometry.setTerminalPoint(new mxPoint(0, 0), true); 1301 edge.geometry.setTerminalPoint(new mxPoint(100, 0), false); 1302 edge.geometry.relative = true; 1303 edge.edge = true; 1304 1305 var cell = new mxCell('', new mxGeometry(0, 0, 20, 14), 'shape=message;html=1;outlineConnect=0;'); 1306 cell.geometry.relative = true; 1307 cell.vertex = true; 1308 cell.geometry.offset = new mxPoint(-10, -7); 1309 edge.insert(cell); 1310 1311 return this.createEdgeTemplateFromCells([edge], 100, 0, 'Connector with Symbol'); 1312 })) 1313 ]; 1314 1315 this.addPaletteFunctions('general', mxResources.get('general'), (expand != null) ? expand : true, fns); 1316 this.setCurrentSearchEntryLibrary(); 1317}; 1318 1319/** 1320 * Adds the general palette to the sidebar. 1321 */ 1322Sidebar.prototype.addMiscPalette = function(expand) 1323{ 1324 var sb = this; 1325 var lineTags = 'line lines connector connectors connection connections arrow arrows ' 1326 this.setCurrentSearchEntryLibrary('general', 'misc'); 1327 1328 var fns = [ 1329 this.createVertexTemplateEntry('text;strokeColor=none;fillColor=none;html=1;fontSize=24;fontStyle=1;verticalAlign=middle;align=center;', 100, 40, 'Title', 'Title', null, null, 'text heading title'), 1330 this.createVertexTemplateEntry('text;strokeColor=none;fillColor=none;html=1;whiteSpace=wrap;verticalAlign=middle;overflow=hidden;', 100, 80, 1331 '<ul><li>Value 1</li><li>Value 2</li><li>Value 3</li></ul>', 'Unordered List'), 1332 this.createVertexTemplateEntry('text;strokeColor=none;fillColor=none;html=1;whiteSpace=wrap;verticalAlign=middle;overflow=hidden;', 100, 80, 1333 '<ol><li>Value 1</li><li>Value 2</li><li>Value 3</li></ol>', 'Ordered List'), 1334 this.addDataEntry('table', 180, 120, 'Table 1', '7ZjBTuMwEIafJtdVnFDoXhtYLnBZeAHTTGtLjieyB9Lu0zNO3FYVVM0upMASKZU8Y49jf3+tX06SF9Xq2sla3WIJJsmvkrxwiNS1qlUBxiRZqsskv0yyLOVfkv060Cva3rSWDiz1Kci6gidpHqHLdAlPaxMTXsk6NEk+hNRMUcXLvBTcbJQmuKvlPPQ3vAnOeZKO7vSfkEo5nqMlqS24WDNHY2TtdTtZN0JpU97INT7S5jWbaBaXB45gdXCLbSru7xqwAnJrHtLoklQcMe0wpAr0Um3KIptU+i6x3NbuiHEjQnsdYN4fIC+ZtDS/YU7SLvuwfMmqdFjfS7cEiokatSVwV09Mw8fcQhtToMGA3KINLyKsY6eBxab2AYmwioGLYLaTtlAmM34YU5H+mCQT3k3BsdjF/IThjgq0nhwLHeYA6akB31vA7N8EPHsH/c6G1c/aMHqn35ulQUa5MNhwqHRZgn3lPyD6cs+Pcj8fCPtkxP4C+2of+QlUOB9VOKTC1hxOIMPF6CGDech6X6ZTWMr0O5+qiw+zlJ8j9k9gKSIdZfgMniLEaCpDm8r0hKYi/uKm/v+dK3H8ij/YQRr4hv81wX+AsXzrm/oRHQZ0Fg53nyPbvr2vlc8='), 1335 this.addDataEntry('table', 180, 120, 'Table 2', '7ZhRb5swEMc/Da+TDSFJX0u7vrQv7bR3NzjBkvEhcynJPv3OYDeLUlS0JURTkUDyne+M+f05nXCUZOXuwYqqeIJc6ii5j5LMAmA3KneZ1DqKmcqj5C6KY0Z3FH/vmeXtLKuElQaHJMRdwpvQW9l5OkeNe+0ddSEqN0Tx6ly3BZa0zTtOw6ZQKF8qsXLzDb0E+WoUFl/UL+diZK/AoFBGWp+zAq1FVat2sS6iUDp/FHvYYnhMsFz0tjSPlF/7aAvNn6bfv7Qod70MWpcH8CChlGj3FNKoHAsfsew4sUKqTRHSPDwm6s6xec89IKWBp/ox4WQ4YdoyKqGf5QqF2QyBfQozt1D9EHYj0TsqUAalvX8jGgHaWmmdgQaniQHjHoRQ+Ukt1yH3FRChDOA9mPdFWyjpLV2EKWPf0iilt8nI5gebLhduMQNTo6Uvwa0hRY2NrHGogPHfCTg7g36zE/1+tsOY8bMKaYyLPgj5zxoBMV1raMgsVJ5L88HHwIcKkHwqwPxC/NNe/uctpP+S/+6Y/QhyzHvlSCY5QkI8nh6Lqb1crL3sj2Uao9sse8tr9oXKa3G1bnPTyz+d+I/fbTjr1WM+6XGFdsP51G8u3W+WI/YbfnoAEAps8YUKjH9+QnCxijo9IAgKLCcFrtFz+v/4byZBRmg6ZB4OQNu5o/PR3w=='), 1336 this.addDataEntry('table title', 180, 150, 'Table with Title 1', '7VjBbqMwEP0arisMpeleQ7u9tJemP+CGCbZkbGRPQtKv37FxGnWTKJVa0q6CBJLnecbg9xg9mSQvm/W95a14NBWoJL9L8tIag/2oWZegVJKlskry2yTLUrqT7M+RWRZm05Zb0PiRgqwvWHG1hB555i8KetThRkXUCd76IYbZfOqQW5zJV4/lKQFzo5FLDZYAFmKleOtkSL8NGUKq6oFvzBK3C22j6YKqZ/FpvporWWsaz2kbfslpa6Qf3a0IcDEpvjpYhPXR7Qco7v0eTANoN5TSyQpFzLjpKUoFyFpsy4oIctcD9Vvtjk0aREIPk5vvkXuUV3pllFw9wRy5rgPFAhsVd9oJiTBr+dyndvSxHCS4sqZ95rYGjMC/pHlsIZUqjTJeJ220fxCaNk4qWGxrXwyiaWJgIzFviwZSiildRFOZ/iqSgnZTUsx2MV0+3WJptENLX4dfA7jDDhx+VMDssICbSHGU6ZSeV18g59Wwcmrts3dyflopQ8wulOkoFLKqQH+mj/KTfXQ9EO3FSPse7ev3lJ9BhetRhWMqsOx8MkxGSxnaUiZntJSbS+6qybdZyu+R9h9gKSwdZfgJnsLYaCpDmwpjZ3QVtn+qv6DGYqeP/IN10sAn/v+T+G9wlos+qp/QYUBroXD36zLMvfuz+Rc='), 1337 this.addDataEntry('table title', 180, 150, 'Table with Title 2', '7VjBbqMwEP0arivAJdtcod1e0ktT7d0NBiwZG9nTQvbrd2xMsy1B7WoTglaVQJp5nhnwe/gdCEhWd3eaNtW9ypkIyG1AMq0U9FHdZUyIIA55HpCbII5DvIP4x8Rq5FbDhmom4TMNcd/wQsUz65FH+iRYjxrYC4+aijY2BLdKUgNUw5b/shgJEdgpCZRLphGIXC4EbQx35TeuouIi39C9eoZh0JClBe9Y/qBa47u1ajc4zPjWAodv/cvYZSp4KTHe4S7tE9NGcRvdviAwzPA7YxpYN8mOgzw1d0zVDPQeS1qeQ+UrrnsGw4rxshraEg9S0wPla++BbAw838e5JyPuJ2nHVwZOxQPbAZWlU6CCWvidthUHtm3ozpa2+C0d5T/XqnmkumTggWOkFVyITAllZZRK2geBanyDYMXQ+6QAVD2o5Yl5HepISVK8kKYs/JYECe4mwzw65HjZcg2ZkgY0fjx2BqMGWmbgswLGxwXce4q9TB/pSU4g59VIzuikekppqw96/rVU4TupFFJbCNViWvE8Z/JfDhL58CBdnYn3ZMT7TxfG4cL5H1ysr00NPpDLctN3rmYSqHsrzp8H5VyCrf4H33sv5rJ8bzWj730fyXlaPZfte6uL+d71pO8tnP95fW9CoAv43vrL987te+sZfS8KR3qSZR+8k56r9cWML4omnW/hAszrfBMKnd/5MD38wXBrb35w/AY='), 1338 this.addDataEntry('crossfunctional cross-functional cross functional flowchart swimlane table', 400, 400, 'Cross-Functional Flowchart', '5ZjfbpswFMafhstNGJK2u1xY05tOmtYn8OAstmRsZB8C6dPvmD9NN6CNqoStTCKSz/GxcX6f+ZAJ4iSv7ywvxFeTgQri2yBOrDHYtvI6AaWCKJRZEH8JoiikXxBtJ3pZ0xsW3ILGUwZE7YA9VyW0Gbq5cx+2pU5RGs198VaZKhXcYlvs8KC6Yid44ZvIf/jUJhVSZff8YErss320saa6lxocdYS+1Kgy188zDukWD/LRT7jqShQvnGzmbkospKV1cg/fwbWFPgt1wXXWBYWRGsHe7olAP/NPo/GhWzWjmCu509ROwZdSoqMAFqGeJNmkOox3YHJAe6CSSmYo2opV2NIOBcidwD+S3LWJ3dPYozDU6LQZ1yke6PQ5RWMpxYaiVDJXXHs9hLHykf48yfiMTrOO9YYuWlkSflwHaxqXUMyOMV2+3GJitEPLZYMBuMMKHM4o1ynSROPSHHoF2hGvKcWiMyi1Gij1TXAHrymVGq0h7Z6jCz8OJyGNx5HWk0if6J0d6XoSabQgpOxqTqZXk0zjBTGNbuZkej1p0i/u0/dp0mfw5bEdfzljvhmo8/aNPj/J63/Hjj8tGOS8JszCBaOc13sZG6DszffFF9p/a75j8lzOfNnwoPmedjqbOPv9Dftlw7PgglDObMDD09qCWF7UgSk8fqZq+n77ivUL'), 1339 this.createVertexTemplateEntry('text;html=1;strokeColor=#c0c0c0;fillColor=#ffffff;overflow=fill;rounded=0;', 280, 160, 1340 '<table border="1" width="100%" height="100%" cellpadding="4" style="width:100%;height:100%;border-collapse:collapse;">' + 1341 '<tr style="background-color:#A7C942;color:#ffffff;border:1px solid #98bf21;"><th align="left">Title 1</th><th align="left">Title 2</th><th align="left">Title 3</th></tr>' + 1342 '<tr style="border:1px solid #98bf21;"><td>Value 1</td><td>Value 2</td><td>Value 3</td></tr>' + 1343 '<tr style="background-color:#EAF2D3;border:1px solid #98bf21;"><td>Value 4</td><td>Value 5</td><td>Value 6</td></tr>' + 1344 '<tr style="border:1px solid #98bf21;"><td>Value 7</td><td>Value 8</td><td>Value 9</td></tr>' + 1345 '<tr style="background-color:#EAF2D3;border:1px solid #98bf21;"><td>Value 10</td><td>Value 11</td><td>Value 12</td></tr></table>', 'HTML Table 1'), 1346 this.createVertexTemplateEntry('text;html=1;strokeColor=#c0c0c0;fillColor=none;overflow=fill;', 180, 140, 1347 '<table border="0" width="100%" height="100%" style="width:100%;height:100%;border-collapse:collapse;">' + 1348 '<tr><td align="center">Value 1</td><td align="center">Value 2</td><td align="center">Value 3</td></tr>' + 1349 '<tr><td align="center">Value 4</td><td align="center">Value 5</td><td align="center">Value 6</td></tr>' + 1350 '<tr><td align="center">Value 7</td><td align="center">Value 8</td><td align="center">Value 9</td></tr></table>', 'HTML Table 2'), 1351 this.createVertexTemplateEntry('text;html=1;strokeColor=none;fillColor=none;overflow=fill;', 180, 140, 1352 '<table border="1" width="100%" height="100%" style="width:100%;height:100%;border-collapse:collapse;">' + 1353 '<tr><td align="center">Value 1</td><td align="center">Value 2</td><td align="center">Value 3</td></tr>' + 1354 '<tr><td align="center">Value 4</td><td align="center">Value 5</td><td align="center">Value 6</td></tr>' + 1355 '<tr><td align="center">Value 7</td><td align="center">Value 8</td><td align="center">Value 9</td></tr></table>', 'HTML Table 3'), 1356 this.createVertexTemplateEntry('text;html=1;strokeColor=none;fillColor=none;overflow=fill;', 160, 140, 1357 '<table border="1" width="100%" height="100%" cellpadding="4" style="width:100%;height:100%;border-collapse:collapse;">' + 1358 '<tr><th align="center"><b>Title</b></th></tr>' + 1359 '<tr><td align="center">Section 1.1\nSection 1.2\nSection 1.3</td></tr>' + 1360 '<tr><td align="center">Section 2.1\nSection 2.2\nSection 2.3</td></tr></table>', 'HTML Table 4'), 1361 this.addEntry('link hyperlink', mxUtils.bind(this, function() 1362 { 1363 var cell = new mxCell('Link', new mxGeometry(0, 0, 60, 40), 'text;html=1;strokeColor=none;fillColor=none;whiteSpace=wrap;align=center;verticalAlign=middle;fontColor=#0000EE;fontStyle=4;'); 1364 cell.vertex = true; 1365 this.graph.setLinkForCell(cell, 'https://www.draw.io'); 1366 1367 return this.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, 'Link'); 1368 })), 1369 this.addEntry('timestamp date time text label', mxUtils.bind(this, function() 1370 { 1371 var cell = new mxCell('%date{ddd mmm dd yyyy HH:MM:ss}%', new mxGeometry(0, 0, 160, 20), 'text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;'); 1372 cell.vertex = true; 1373 this.graph.setAttributeForCell(cell, 'placeholders', '1'); 1374 1375 return this.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, 'Timestamp'); 1376 })), 1377 this.addEntry('variable placeholder metadata hello world text label', mxUtils.bind(this, function() 1378 { 1379 var cell = new mxCell('%name% Text', new mxGeometry(0, 0, 80, 20), 'text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;'); 1380 cell.vertex = true; 1381 this.graph.setAttributeForCell(cell, 'placeholders', '1'); 1382 this.graph.setAttributeForCell(cell, 'name', 'Variable'); 1383 1384 return this.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, 'Variable'); 1385 })), 1386 this.createVertexTemplateEntry('shape=ext;double=1;rounded=0;whiteSpace=wrap;html=1;', 120, 80, '', 'Double Rectangle', null, null, 'rect rectangle box double'), 1387 this.createVertexTemplateEntry('shape=ext;double=1;rounded=1;whiteSpace=wrap;html=1;', 120, 80, '', 'Double Rounded Rectangle', null, null, 'rounded rect rectangle box double'), 1388 this.createVertexTemplateEntry('ellipse;shape=doubleEllipse;whiteSpace=wrap;html=1;', 100, 60, '', 'Double Ellipse', null, null, 'oval ellipse start end state double'), 1389 this.createVertexTemplateEntry('shape=ext;double=1;whiteSpace=wrap;html=1;aspect=fixed;', 80, 80, '', 'Double Square', null, null, 'double square'), 1390 this.createVertexTemplateEntry('ellipse;shape=doubleEllipse;whiteSpace=wrap;html=1;aspect=fixed;', 80, 80, '', 'Double Circle', null, null, 'double circle'), 1391 this.createVertexTemplateEntry('rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillWeight=4;hachureGap=8;hachureAngle=45;fillColor=#1ba1e2;sketch=1;', 120, 60, '', 'Rectangle Sketch', true, null, 'rectangle rect box text sketch comic retro'), 1392 this.createVertexTemplateEntry('ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillWeight=2;hachureGap=8;fillColor=#990000;fillStyle=dots;sketch=1;', 120, 60, '', 'Ellipse Sketch', true, null, 'ellipse oval sketch comic retro'), 1393 this.createVertexTemplateEntry('rhombus;whiteSpace=wrap;html=1;strokeWidth=2;fillWeight=-1;hachureGap=8;fillStyle=cross-hatch;fillColor=#006600;sketch=1;', 120, 60, '', 'Diamond Sketch', true, null, 'diamond sketch comic retro'), 1394 this.createVertexTemplateEntry('html=1;whiteSpace=wrap;shape=isoCube2;backgroundOutline=1;isoAngle=15;', 90, 100, '', 'Isometric Cube', true, null, 'cube box iso isometric'), 1395 this.createVertexTemplateEntry('html=1;whiteSpace=wrap;aspect=fixed;shape=isoRectangle;', 150, 90, '', 'Isometric Square', true, null, 'rectangle rect box iso isometric'), 1396 this.createEdgeTemplateEntry('edgeStyle=isometricEdgeStyle;endArrow=none;html=1;', 50, 100, '', 'Isometric Edge 1'), 1397 this.createEdgeTemplateEntry('edgeStyle=isometricEdgeStyle;endArrow=none;html=1;elbow=vertical;', 50, 100, '', 'Isometric Edge 2'), 1398 this.createVertexTemplateEntry('shape=curlyBracket;whiteSpace=wrap;html=1;rounded=1;', 20, 120, '', 'Left Curly Bracket'), 1399 this.createVertexTemplateEntry('shape=curlyBracket;whiteSpace=wrap;html=1;rounded=1;flipH=1;', 20, 120, '', 'Right Curly Bracket'), 1400 this.createVertexTemplateEntry('line;strokeWidth=2;html=1;', 160, 10, '', 'Horizontal Line'), 1401 this.createVertexTemplateEntry('line;strokeWidth=2;direction=south;html=1;', 10, 160, '', 'Vertical Line'), 1402 this.createVertexTemplateEntry('line;strokeWidth=4;html=1;perimeter=backbonePerimeter;points=[];outlineConnect=0;', 160, 10, '', 'Horizontal Backbone', false, null, 'backbone bus network'), 1403 this.createVertexTemplateEntry('line;strokeWidth=4;direction=south;html=1;perimeter=backbonePerimeter;points=[];outlineConnect=0;', 10, 160, '', 'Vertical Backbone', false, null, 'backbone bus network'), 1404 this.createVertexTemplateEntry('shape=crossbar;whiteSpace=wrap;html=1;rounded=1;', 120, 20, '', 'Horizontal Crossbar', false, null, 'crossbar distance measure dimension unit'), 1405 this.createVertexTemplateEntry('shape=crossbar;whiteSpace=wrap;html=1;rounded=1;direction=south;', 20, 120, '', 'Vertical Crossbar', false, null, 'crossbar distance measure dimension unit'), 1406 this.createVertexTemplateEntry('shape=image;html=1;verticalLabelPosition=bottom;verticalAlign=top;imageAspect=1;aspect=fixed;image=' + this.gearImage, 52, 61, '', 'Image (Fixed Aspect)', false, null, 'fixed image icon symbol'), 1407 this.createVertexTemplateEntry('shape=image;html=1;verticalLabelPosition=bottom;verticalAlign=top;imageAspect=0;image=' + this.gearImage, 50, 60, '', 'Image (Variable Aspect)', false, null, 'strechted image icon symbol'), 1408 this.createVertexTemplateEntry('icon;html=1;image=' + this.gearImage, 60, 60, 'Icon', 'Icon', false, null, 'icon image symbol'), 1409 this.createVertexTemplateEntry('label;whiteSpace=wrap;html=1;image=' + this.gearImage, 140, 60, 'Label', 'Label 1', null, null, 'label image icon symbol'), 1410 this.createVertexTemplateEntry('label;whiteSpace=wrap;html=1;align=center;verticalAlign=bottom;spacingLeft=0;spacingBottom=4;imageAlign=center;imageVerticalAlign=top;image=' + this.gearImage, 120, 80, 'Label', 'Label 2', null, null, 'label image icon symbol'), 1411 this.addEntry('shape group container', function() 1412 { 1413 var cell = new mxCell('Label', new mxGeometry(0, 0, 160, 70), 1414 'html=1;whiteSpace=wrap;container=1;recursiveResize=0;collapsible=0;'); 1415 cell.vertex = true; 1416 1417 var symbol = new mxCell('', new mxGeometry(20, 20, 20, 30), 'triangle;html=1;whiteSpace=wrap;'); 1418 symbol.vertex = true; 1419 cell.insert(symbol); 1420 1421 return sb.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, 'Shape Group'); 1422 }), 1423 this.createVertexTemplateEntry('shape=partialRectangle;whiteSpace=wrap;html=1;left=0;right=0;fillColor=none;', 120, 60, '', 'Partial Rectangle'), 1424 this.createVertexTemplateEntry('shape=partialRectangle;whiteSpace=wrap;html=1;bottom=0;top=0;fillColor=none;', 120, 60, '', 'Partial Rectangle'), 1425 this.createVertexTemplateEntry('shape=partialRectangle;whiteSpace=wrap;html=1;bottom=0;right=0;fillColor=none;', 120, 60, '', 'Partial Rectangle'), 1426 this.createVertexTemplateEntry('shape=partialRectangle;whiteSpace=wrap;html=1;bottom=1;right=1;left=1;top=0;fillColor=none;routingCenterX=-0.5;', 120, 60, '', 'Partial Rectangle'), 1427 this.createVertexTemplateEntry('shape=waypoint;sketch=0;fillStyle=solid;size=6;pointerEvents=1;points=[];fillColor=none;resizable=0;rotatable=0;perimeter=centerPerimeter;snapToPoint=1;', 40, 40, '', 'Waypoint'), 1428 this.createEdgeTemplateEntry('edgeStyle=segmentEdgeStyle;endArrow=classic;html=1;', 50, 50, '', 'Manual Line', null, lineTags + 'manual'), 1429 this.createEdgeTemplateEntry('shape=filledEdge;rounded=0;fixDash=1;endArrow=none;strokeWidth=10;fillColor=#ffffff;edgeStyle=orthogonalEdgeStyle;', 60, 40, '', 'Filled Edge'), 1430 this.createEdgeTemplateEntry('edgeStyle=elbowEdgeStyle;elbow=horizontal;endArrow=classic;html=1;', 50, 50, '', 'Horizontal Elbow', null, lineTags + 'elbow horizontal'), 1431 this.createEdgeTemplateEntry('edgeStyle=elbowEdgeStyle;elbow=vertical;endArrow=classic;html=1;', 50, 50, '', 'Vertical Elbow', null, lineTags + 'elbow vertical') 1432 ]; 1433 1434 this.addPaletteFunctions('misc', mxResources.get('misc'), (expand != null) ? expand : true, fns); 1435 this.setCurrentSearchEntryLibrary(); 1436}; 1437/** 1438 * Adds the container palette to the sidebar. 1439 */ 1440Sidebar.prototype.addAdvancedPalette = function(expand) 1441{ 1442 this.setCurrentSearchEntryLibrary('general', 'advanced'); 1443 this.addPaletteFunctions('advanced', mxResources.get('advanced'), (expand != null) ? expand : false, this.createAdvancedShapes()); 1444 this.setCurrentSearchEntryLibrary(); 1445}; 1446 1447/** 1448 * Adds the general palette to the sidebar. 1449 */ 1450Sidebar.prototype.addBasicPalette = function(dir) 1451{ 1452 this.setCurrentSearchEntryLibrary('basic'); 1453 this.addStencilPalette('basic', mxResources.get('basic'), dir + '/basic.xml', 1454 ';whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;strokeWidth=2', 1455 null, null, null, null, [ 1456 this.createVertexTemplateEntry('shape=partialRectangle;whiteSpace=wrap;html=1;top=0;bottom=0;fillColor=none;', 120, 60, '', 'Partial Rectangle'), 1457 this.createVertexTemplateEntry('shape=partialRectangle;whiteSpace=wrap;html=1;right=0;top=0;bottom=0;fillColor=none;routingCenterX=-0.5;', 120, 60, '', 'Partial Rectangle'), 1458 this.createVertexTemplateEntry('shape=partialRectangle;whiteSpace=wrap;html=1;bottom=0;right=0;fillColor=none;', 120, 60, '', 'Partial Rectangle'), 1459 this.createVertexTemplateEntry('shape=partialRectangle;whiteSpace=wrap;html=1;top=0;left=0;fillColor=none;', 120, 60, '', 'Partial Rectangle') 1460 ]); 1461 this.setCurrentSearchEntryLibrary(); 1462}; 1463 1464/** 1465 * Adds the container palette to the sidebar. 1466 */ 1467Sidebar.prototype.createAdvancedShapes = function() 1468{ 1469 // Avoids having to bind all functions to "this" 1470 var sb = this; 1471 1472 // Reusable cells 1473 var field = new mxCell('List Item', new mxGeometry(0, 0, 60, 26), 'text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;'); 1474 field.vertex = true; 1475 1476 return [ 1477 this.createVertexTemplateEntry('shape=tapeData;whiteSpace=wrap;html=1;perimeter=ellipsePerimeter;', 80, 80, '', 'Tape Data'), 1478 this.createVertexTemplateEntry('shape=manualInput;whiteSpace=wrap;html=1;', 80, 80, '', 'Manual Input'), 1479 this.createVertexTemplateEntry('shape=loopLimit;whiteSpace=wrap;html=1;', 100, 80, '', 'Loop Limit'), 1480 this.createVertexTemplateEntry('shape=offPageConnector;whiteSpace=wrap;html=1;', 80, 80, '', 'Off Page Connector'), 1481 this.createVertexTemplateEntry('shape=delay;whiteSpace=wrap;html=1;', 80, 40, '', 'Delay'), 1482 this.createVertexTemplateEntry('shape=display;whiteSpace=wrap;html=1;', 80, 40, '', 'Display'), 1483 this.createVertexTemplateEntry('shape=singleArrow;direction=west;whiteSpace=wrap;html=1;', 100, 60, '', 'Arrow Left'), 1484 this.createVertexTemplateEntry('shape=singleArrow;whiteSpace=wrap;html=1;', 100, 60, '', 'Arrow Right'), 1485 this.createVertexTemplateEntry('shape=singleArrow;direction=north;whiteSpace=wrap;html=1;', 60, 100, '', 'Arrow Up'), 1486 this.createVertexTemplateEntry('shape=singleArrow;direction=south;whiteSpace=wrap;html=1;', 60, 100, '', 'Arrow Down'), 1487 this.createVertexTemplateEntry('shape=doubleArrow;whiteSpace=wrap;html=1;', 100, 60, '', 'Double Arrow'), 1488 this.createVertexTemplateEntry('shape=doubleArrow;direction=south;whiteSpace=wrap;html=1;', 60, 100, '', 'Double Arrow Vertical', null, null, 'double arrow'), 1489 this.createVertexTemplateEntry('shape=actor;whiteSpace=wrap;html=1;', 40, 60, '', 'User', null, null, 'user person human'), 1490 this.createVertexTemplateEntry('shape=cross;whiteSpace=wrap;html=1;', 80, 80, '', 'Cross'), 1491 this.createVertexTemplateEntry('shape=corner;whiteSpace=wrap;html=1;', 80, 80, '', 'Corner'), 1492 this.createVertexTemplateEntry('shape=tee;whiteSpace=wrap;html=1;', 80, 80, '', 'Tee'), 1493 this.createVertexTemplateEntry('shape=datastore;whiteSpace=wrap;html=1;', 60, 60, '', 'Data Store', null, null, 'data store cylinder database'), 1494 this.createVertexTemplateEntry('shape=orEllipse;perimeter=ellipsePerimeter;whiteSpace=wrap;html=1;backgroundOutline=1;', 80, 80, '', 'Or', null, null, 'or circle oval ellipse'), 1495 this.createVertexTemplateEntry('shape=sumEllipse;perimeter=ellipsePerimeter;whiteSpace=wrap;html=1;backgroundOutline=1;', 80, 80, '', 'Sum', null, null, 'sum circle oval ellipse'), 1496 this.createVertexTemplateEntry('shape=lineEllipse;perimeter=ellipsePerimeter;whiteSpace=wrap;html=1;backgroundOutline=1;', 80, 80, '', 'Ellipse with horizontal divider', null, null, 'circle oval ellipse'), 1497 this.createVertexTemplateEntry('shape=lineEllipse;line=vertical;perimeter=ellipsePerimeter;whiteSpace=wrap;html=1;backgroundOutline=1;', 80, 80, '', 'Ellipse with vertical divider', null, null, 'circle oval ellipse'), 1498 this.createVertexTemplateEntry('shape=sortShape;perimeter=rhombusPerimeter;whiteSpace=wrap;html=1;', 80, 80, '', 'Sort', null, null, 'sort'), 1499 this.createVertexTemplateEntry('shape=collate;whiteSpace=wrap;html=1;', 80, 80, '', 'Collate', null, null, 'collate'), 1500 this.createVertexTemplateEntry('shape=switch;whiteSpace=wrap;html=1;', 60, 60, '', 'Switch', null, null, 'switch router'), 1501 this.addEntry('process bar', function() 1502 { 1503 return sb.createVertexTemplateFromData('zZXRaoMwFIafJpcDjbNrb2233rRQ8AkyPdPQaCRJV+3T7yTG2rUVBoOtgpDzn/xJzncCIdGyateKNeVW5iBI9EqipZLS9KOqXYIQhAY8J9GKUBrgT+jbRDZ02aBhCmrzEwPtDZ9MHKBXdkpmoDWKCVN9VptO+Kw+8kqwGqMkK7nIN6yTB7uTNizbD1FSSsVPsjYMC1qFKHxwIZZSSIVxLZ1/nJNar5+oQPMT7IYCrqUta1ENzuqGaeOFTArBGs3f3Vmtoo2Se7ja1h00kSoHK4bBIKUNy3hdoPYU0mF91i9mT8EEL2ocZ3gKa00ayWujLZY4IfHKFonVDLsRGgXuQ90zBmWgneyTk3yT1iArMKrDKUeem9L3ajHrbSXwohxsQd/ggOleKM7ese048J2/fwuim1uQGmhQCW8vQMkacP3GCQgBFMftHEsr7cYYe95CnmKTPMFbYD8CQ++DGQy+/M5X4ku5wHYmdIktfvk9tecpavThqS3m/0YtnqIWPTy1cD77K2wYjo+Ay317I74A', 296, 100, 'Process Bar'); 1504 }), 1505 this.createVertexTemplateEntry('swimlane;', 200, 200, 'Container', 'Container', null, null, 'container swimlane lane pool group'), 1506 this.addEntry('list group erd table', function() 1507 { 1508 var cell = new mxCell('List', new mxGeometry(0, 0, 140, 110), 1509 'swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=26;fillColor=none;horizontalStack=0;' + 1510 'resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;'); 1511 cell.vertex = true; 1512 cell.insert(sb.cloneCell(field, 'Item 1')); 1513 cell.insert(sb.cloneCell(field, 'Item 2')); 1514 cell.insert(sb.cloneCell(field, 'Item 3')); 1515 1516 return sb.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, 'List'); 1517 }), 1518 this.addEntry('list item entry value group erd table', function() 1519 { 1520 return sb.createVertexTemplateFromCells([sb.cloneCell(field, 'List Item')], field.geometry.width, field.geometry.height, 'List Item'); 1521 }) 1522 ]; 1523}; 1524 1525/** 1526 * Adds the container palette to the sidebar. 1527 */ 1528Sidebar.prototype.createAdvancedShapes = function() 1529{ 1530 // Avoids having to bind all functions to "this" 1531 var sb = this; 1532 1533 // Reusable cells 1534 var field = new mxCell('List Item', new mxGeometry(0, 0, 60, 26), 'text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;'); 1535 field.vertex = true; 1536 1537 return [ 1538 this.createVertexTemplateEntry('shape=tapeData;whiteSpace=wrap;html=1;perimeter=ellipsePerimeter;', 80, 80, '', 'Tape Data'), 1539 this.createVertexTemplateEntry('shape=manualInput;whiteSpace=wrap;html=1;', 80, 80, '', 'Manual Input'), 1540 this.createVertexTemplateEntry('shape=loopLimit;whiteSpace=wrap;html=1;', 100, 80, '', 'Loop Limit'), 1541 this.createVertexTemplateEntry('shape=offPageConnector;whiteSpace=wrap;html=1;', 80, 80, '', 'Off Page Connector'), 1542 this.createVertexTemplateEntry('shape=delay;whiteSpace=wrap;html=1;', 80, 40, '', 'Delay'), 1543 this.createVertexTemplateEntry('shape=display;whiteSpace=wrap;html=1;', 80, 40, '', 'Display'), 1544 this.createVertexTemplateEntry('shape=singleArrow;direction=west;whiteSpace=wrap;html=1;', 100, 60, '', 'Arrow Left'), 1545 this.createVertexTemplateEntry('shape=singleArrow;whiteSpace=wrap;html=1;', 100, 60, '', 'Arrow Right'), 1546 this.createVertexTemplateEntry('shape=singleArrow;direction=north;whiteSpace=wrap;html=1;', 60, 100, '', 'Arrow Up'), 1547 this.createVertexTemplateEntry('shape=singleArrow;direction=south;whiteSpace=wrap;html=1;', 60, 100, '', 'Arrow Down'), 1548 this.createVertexTemplateEntry('shape=doubleArrow;whiteSpace=wrap;html=1;', 100, 60, '', 'Double Arrow'), 1549 this.createVertexTemplateEntry('shape=doubleArrow;direction=south;whiteSpace=wrap;html=1;', 60, 100, '', 'Double Arrow Vertical', null, null, 'double arrow'), 1550 this.createVertexTemplateEntry('shape=actor;whiteSpace=wrap;html=1;', 40, 60, '', 'User', null, null, 'user person human'), 1551 this.createVertexTemplateEntry('shape=cross;whiteSpace=wrap;html=1;', 80, 80, '', 'Cross'), 1552 this.createVertexTemplateEntry('shape=corner;whiteSpace=wrap;html=1;', 80, 80, '', 'Corner'), 1553 this.createVertexTemplateEntry('shape=tee;whiteSpace=wrap;html=1;', 80, 80, '', 'Tee'), 1554 this.createVertexTemplateEntry('shape=datastore;whiteSpace=wrap;html=1;', 60, 60, '', 'Data Store', null, null, 'data store cylinder database'), 1555 this.createVertexTemplateEntry('shape=orEllipse;perimeter=ellipsePerimeter;whiteSpace=wrap;html=1;backgroundOutline=1;', 80, 80, '', 'Or', null, null, 'or circle oval ellipse'), 1556 this.createVertexTemplateEntry('shape=sumEllipse;perimeter=ellipsePerimeter;whiteSpace=wrap;html=1;backgroundOutline=1;', 80, 80, '', 'Sum', null, null, 'sum circle oval ellipse'), 1557 this.createVertexTemplateEntry('shape=lineEllipse;perimeter=ellipsePerimeter;whiteSpace=wrap;html=1;backgroundOutline=1;', 80, 80, '', 'Ellipse with horizontal divider', null, null, 'circle oval ellipse'), 1558 this.createVertexTemplateEntry('shape=lineEllipse;line=vertical;perimeter=ellipsePerimeter;whiteSpace=wrap;html=1;backgroundOutline=1;', 80, 80, '', 'Ellipse with vertical divider', null, null, 'circle oval ellipse'), 1559 this.createVertexTemplateEntry('shape=sortShape;perimeter=rhombusPerimeter;whiteSpace=wrap;html=1;', 80, 80, '', 'Sort', null, null, 'sort'), 1560 this.createVertexTemplateEntry('shape=collate;whiteSpace=wrap;html=1;', 80, 80, '', 'Collate', null, null, 'collate'), 1561 this.createVertexTemplateEntry('shape=switch;whiteSpace=wrap;html=1;', 60, 60, '', 'Switch', null, null, 'switch router'), 1562 this.addEntry('process bar', function() 1563 { 1564 return sb.createVertexTemplateFromData('zZXRaoMwFIafJpcDjbNrb2233rRQ8AkyPdPQaCRJV+3T7yTG2rUVBoOtgpDzn/xJzncCIdGyateKNeVW5iBI9EqipZLS9KOqXYIQhAY8J9GKUBrgT+jbRDZ02aBhCmrzEwPtDZ9MHKBXdkpmoDWKCVN9VptO+Kw+8kqwGqMkK7nIN6yTB7uTNizbD1FSSsVPsjYMC1qFKHxwIZZSSIVxLZ1/nJNar5+oQPMT7IYCrqUta1ENzuqGaeOFTArBGs3f3Vmtoo2Se7ja1h00kSoHK4bBIKUNy3hdoPYU0mF91i9mT8EEL2ocZ3gKa00ayWujLZY4IfHKFonVDLsRGgXuQ90zBmWgneyTk3yT1iArMKrDKUeem9L3ajHrbSXwohxsQd/ggOleKM7ese048J2/fwuim1uQGmhQCW8vQMkacP3GCQgBFMftHEsr7cYYe95CnmKTPMFbYD8CQ++DGQy+/M5X4ku5wHYmdIktfvk9tecpavThqS3m/0YtnqIWPTy1cD77K2wYjo+Ay317I74A', 296, 100, 'Process Bar'); 1565 }), 1566 this.createVertexTemplateEntry('swimlane;', 200, 200, 'Container', 'Container', null, null, 'container swimlane lane pool group'), 1567 this.addEntry('list group erd table', function() 1568 { 1569 var cell = new mxCell('List', new mxGeometry(0, 0, 140, 110), 1570 'swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=26;fillColor=none;horizontalStack=0;' + 1571 'resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;'); 1572 cell.vertex = true; 1573 cell.insert(sb.cloneCell(field, 'Item 1')); 1574 cell.insert(sb.cloneCell(field, 'Item 2')); 1575 cell.insert(sb.cloneCell(field, 'Item 3')); 1576 1577 return sb.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, 'List'); 1578 }), 1579 this.addEntry('list item entry value group erd table', function() 1580 { 1581 return sb.createVertexTemplateFromCells([sb.cloneCell(field, 'List Item')], field.geometry.width, field.geometry.height, 'List Item'); 1582 }) 1583 ]; 1584}; 1585 1586/** 1587 * Adds the general palette to the sidebar. 1588 */ 1589Sidebar.prototype.addBasicPalette = function(dir) 1590{ 1591 this.setCurrentSearchEntryLibrary('basic'); 1592 this.addStencilPalette('basic', mxResources.get('basic'), dir + '/basic.xml', 1593 ';whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;strokeWidth=2', 1594 null, null, null, null, [ 1595 this.createVertexTemplateEntry('shape=partialRectangle;whiteSpace=wrap;html=1;top=0;bottom=0;fillColor=none;', 120, 60, '', 'Partial Rectangle'), 1596 this.createVertexTemplateEntry('shape=partialRectangle;whiteSpace=wrap;html=1;right=0;top=0;bottom=0;fillColor=none;routingCenterX=-0.5;', 120, 60, '', 'Partial Rectangle'), 1597 this.createVertexTemplateEntry('shape=partialRectangle;whiteSpace=wrap;html=1;bottom=0;right=0;fillColor=none;', 120, 60, '', 'Partial Rectangle'), 1598 this.createVertexTemplateEntry('shape=partialRectangle;whiteSpace=wrap;html=1;top=0;left=0;fillColor=none;', 120, 60, '', 'Partial Rectangle') 1599 ]); 1600 this.setCurrentSearchEntryLibrary(); 1601}; 1602 1603/** 1604 * Adds the general palette to the sidebar. 1605 */ 1606Sidebar.prototype.addUmlPalette = function(expand) 1607{ 1608 // Avoids having to bind all functions to "this" 1609 var sb = this; 1610 1611 // Reusable cells 1612 var field = new mxCell('+ field: type', new mxGeometry(0, 0, 100, 26), 'text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;'); 1613 field.vertex = true; 1614 1615 var divider = new mxCell('', new mxGeometry(0, 0, 40, 8), 'line;strokeWidth=1;fillColor=none;align=left;verticalAlign=middle;spacingTop=-1;spacingLeft=3;spacingRight=3;rotatable=0;labelPosition=right;points=[];portConstraint=eastwest;'); 1616 divider.vertex = true; 1617 1618 // Default tags 1619 var dt = 'uml static class '; 1620 this.setCurrentSearchEntryLibrary('uml'); 1621 1622 var fns = [ 1623 this.createVertexTemplateEntry('html=1;', 110, 50, 'Object', 'Object', null, null, dt + 'object instance'), 1624 this.createVertexTemplateEntry('html=1;', 110, 50, '«interface»<br><b>Name</b>', 'Interface', null, null, dt + 'interface object instance annotated annotation'), 1625 this.addEntry(dt + 'object instance', function() 1626 { 1627 var cell = new mxCell('Classname', new mxGeometry(0, 0, 160, 90), 1628 'swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;'); 1629 cell.vertex = true; 1630 cell.insert(field.clone()); 1631 cell.insert(divider.clone()); 1632 cell.insert(sb.cloneCell(field, '+ method(type): type')); 1633 1634 return sb.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, 'Class'); 1635 }), 1636 this.addEntry(dt + 'section subsection', function() 1637 { 1638 var cell = new mxCell('Classname', new mxGeometry(0, 0, 140, 110), 1639 'swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=26;fillColor=none;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;'); 1640 cell.vertex = true; 1641 cell.insert(field.clone()); 1642 cell.insert(field.clone()); 1643 cell.insert(field.clone()); 1644 1645 return sb.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, 'Class 2'); 1646 }), 1647 this.addEntry(dt + 'item member method function variable field attribute label', function() 1648 { 1649 return sb.createVertexTemplateFromCells([sb.cloneCell(field, '+ item: attribute')], field.geometry.width, field.geometry.height, 'Item 1'); 1650 }), 1651 this.addEntry(dt + 'item member method function variable field attribute label', function() 1652 { 1653 var cell = new mxCell('item: attribute', new mxGeometry(0, 0, 120, field.geometry.height), 'label;fontStyle=0;strokeColor=none;fillColor=none;align=left;verticalAlign=top;overflow=hidden;' + 1654 'spacingLeft=28;spacingRight=4;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;imageWidth=16;imageHeight=16;image=' + sb.gearImage); 1655 cell.vertex = true; 1656 1657 return sb.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, 'Item 2'); 1658 }), 1659 this.addEntry(dt + 'divider hline line separator', function() 1660 { 1661 return sb.createVertexTemplateFromCells([divider.clone()], divider.geometry.width, divider.geometry.height, 'Divider'); 1662 }), 1663 this.addEntry(dt + 'spacer space gap separator', function() 1664 { 1665 var cell = new mxCell('', new mxGeometry(0, 0, 20, 14), 'text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingTop=-1;spacingLeft=4;spacingRight=4;rotatable=0;labelPosition=right;points=[];portConstraint=eastwest;'); 1666 cell.vertex = true; 1667 1668 return sb.createVertexTemplateFromCells([cell.clone()], cell.geometry.width, cell.geometry.height, 'Spacer'); 1669 }), 1670 this.createVertexTemplateEntry('text;align=center;fontStyle=1;verticalAlign=middle;spacingLeft=3;spacingRight=3;strokeColor=none;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;', 1671 80, 26, 'Title', 'Title', null, null, dt + 'title label'), 1672 this.addEntry(dt + 'component', function() 1673 { 1674 var cell = new mxCell('«Annotation»<br/><b>Component</b>', new mxGeometry(0, 0, 180, 90), 'html=1;dropTarget=0;'); 1675 cell.vertex = true; 1676 1677 var symbol = new mxCell('', new mxGeometry(1, 0, 20, 20), 'shape=module;jettyWidth=8;jettyHeight=4;'); 1678 symbol.vertex = true; 1679 symbol.geometry.relative = true; 1680 symbol.geometry.offset = new mxPoint(-27, 7); 1681 cell.insert(symbol); 1682 1683 return sb.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, 'Component'); 1684 }), 1685 this.addEntry(dt + 'component', function() 1686 { 1687 var cell = new mxCell('<p style="margin:0px;margin-top:6px;text-align:center;"><b>Component</b></p>' + 1688 '<hr/><p style="margin:0px;margin-left:8px;">+ Attribute1: Type<br/>+ Attribute2: Type</p>', new mxGeometry(0, 0, 180, 90), 1689 'align=left;overflow=fill;html=1;dropTarget=0;'); 1690 cell.vertex = true; 1691 1692 var symbol = new mxCell('', new mxGeometry(1, 0, 20, 20), 'shape=component;jettyWidth=8;jettyHeight=4;'); 1693 symbol.vertex = true; 1694 symbol.geometry.relative = true; 1695 symbol.geometry.offset = new mxPoint(-24, 4); 1696 cell.insert(symbol); 1697 1698 return sb.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, 'Component with Attributes'); 1699 }), 1700 this.createVertexTemplateEntry('verticalAlign=top;align=left;spacingTop=8;spacingLeft=2;spacingRight=12;shape=cube;size=10;direction=south;fontStyle=4;html=1;', 1701 180, 120, 'Block', 'Block', null, null, dt + 'block'), 1702 this.createVertexTemplateEntry('shape=module;align=left;spacingLeft=20;align=center;verticalAlign=top;', 100, 50, 'Module', 'Module', null, null, dt + 'module component'), 1703 this.createVertexTemplateEntry('shape=folder;fontStyle=1;spacingTop=10;tabWidth=40;tabHeight=14;tabPosition=left;html=1;', 70, 50, 1704 'package', 'Package', null, null, dt + 'package'), 1705 this.createVertexTemplateEntry('verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;', 1706 160, 90, '<p style="margin:0px;margin-top:4px;text-align:center;text-decoration:underline;"><b>Object:Type</b></p><hr/>' + 1707 '<p style="margin:0px;margin-left:8px;">field1 = value1<br/>field2 = value2<br>field3 = value3</p>', 'Object', 1708 null, null, dt + 'object instance'), 1709 this.createVertexTemplateEntry('verticalAlign=top;align=left;overflow=fill;html=1;',180, 90, 1710 '<div style="box-sizing:border-box;width:100%;background:#e4e4e4;padding:2px;">Tablename</div>' + 1711 '<table style="width:100%;font-size:1em;" cellpadding="2" cellspacing="0">' + 1712 '<tr><td>PK</td><td>uniqueId</td></tr><tr><td>FK1</td><td>' + 1713 'foreignKey</td></tr><tr><td></td><td>fieldname</td></tr></table>', 'Entity', null, null, 'er entity table'), 1714 this.addEntry(dt + 'object instance', function() 1715 { 1716 var cell = new mxCell('<p style="margin:0px;margin-top:4px;text-align:center;">' + 1717 '<b>Class</b></p>' + 1718 '<hr size="1"/><div style="height:2px;"></div>', new mxGeometry(0, 0, 140, 60), 1719 'verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;'); 1720 cell.vertex = true; 1721 1722 return sb.createVertexTemplateFromCells([cell.clone()], cell.geometry.width, cell.geometry.height, 'Class 3'); 1723 }), 1724 this.addEntry(dt + 'object instance', function() 1725 { 1726 var cell = new mxCell('<p style="margin:0px;margin-top:4px;text-align:center;">' + 1727 '<b>Class</b></p>' + 1728 '<hr size="1"/><div style="height:2px;"></div><hr size="1"/><div style="height:2px;"></div>', new mxGeometry(0, 0, 140, 60), 1729 'verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;'); 1730 cell.vertex = true; 1731 1732 return sb.createVertexTemplateFromCells([cell.clone()], cell.geometry.width, cell.geometry.height, 'Class 4'); 1733 }), 1734 this.addEntry(dt + 'object instance', function() 1735 { 1736 var cell = new mxCell('<p style="margin:0px;margin-top:4px;text-align:center;">' + 1737 '<b>Class</b></p>' + 1738 '<hr size="1"/><p style="margin:0px;margin-left:4px;">+ field: Type</p><hr size="1"/>' + 1739 '<p style="margin:0px;margin-left:4px;">+ method(): Type</p>', new mxGeometry(0, 0, 160, 90), 1740 'verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;'); 1741 cell.vertex = true; 1742 1743 return sb.createVertexTemplateFromCells([cell.clone()], cell.geometry.width, cell.geometry.height, 'Class 5'); 1744 }), 1745 this.addEntry(dt + 'object instance', function() 1746 { 1747 var cell = new mxCell('<p style="margin:0px;margin-top:4px;text-align:center;">' + 1748 '<i><<Interface>></i><br/><b>Interface</b></p>' + 1749 '<hr size="1"/><p style="margin:0px;margin-left:4px;">+ field1: Type<br/>' + 1750 '+ field2: Type</p>' + 1751 '<hr size="1"/><p style="margin:0px;margin-left:4px;">' + 1752 '+ method1(Type): Type<br/>' + 1753 '+ method2(Type, Type): Type</p>', new mxGeometry(0, 0, 190, 140), 1754 'verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;'); 1755 cell.vertex = true; 1756 1757 return sb.createVertexTemplateFromCells([cell.clone()], cell.geometry.width, cell.geometry.height, 'Interface 2'); 1758 }), 1759 this.createVertexTemplateEntry('shape=providedRequiredInterface;html=1;verticalLabelPosition=bottom;sketch=0;', 20, 20, '', 'Provided/Required Interface', null, null, 'uml provided required interface lollipop notation'), 1760 this.createVertexTemplateEntry('shape=requiredInterface;html=1;verticalLabelPosition=bottom;sketch=0;', 10, 20, '', 'Required Interface', null, null, 'uml required interface lollipop notation'), 1761 this.addEntry('uml lollipop notation provided required interface', function() 1762 { 1763 return sb.createVertexTemplateFromData('zVRNT8MwDP01uaLSMu6sfFxAmrQDcAytaQJZXLnu2u7XkzQZXTUmuIA4VIqf/ZzkvdQiyzf9HclaPWAJRmQ3IssJkcNq0+dgjEgTXYrsWqRp4j6R3p7Ino/ZpJYEln9CSANhK00LAQlAw4OJAGFrS/D1iciWSKywQivNPWLtwHMHvgHzsNY7z5Ato4MUb0zMgi2viLBzoUULAbnVxsSWzTtwofYBtlTACkhvgIHWtSy0rWKSJVXAJ5Lh4FBWMNMicAJ0cSzPWBW1uQN0fWlwJQRGst7OW8kmhNVn3Sd1hdp1TJMhVCzmhHipUDO54RYHm07Q6NHXfmV/65eS5jXXVJhj15yCNDz54GyxD58PwjL2v/SmMuE7POqSVdxj5vm/cK6PG4X/5deNvPjeSEfQdeOV75Rm8K/dZzo3LOaGSaMr69aF0wbIA00NhZfpVff+JSwJGr2TL2Nnr3jtbzDeabEUi2v/Tlo22kKO1gbq0Z8ZDwzE0J+cNidM2ROinF18CR6KeivQleI59pVrM8knfV04Dc1gx+FM/QA=', 1764 40, 10, 'Lollipop Notation'); 1765 }), 1766 this.createVertexTemplateEntry('shape=umlBoundary;whiteSpace=wrap;html=1;', 100, 80, 'Boundary Object', 'Boundary Object', null, null, 'uml boundary object'), 1767 this.createVertexTemplateEntry('ellipse;shape=umlEntity;whiteSpace=wrap;html=1;', 80, 80, 'Entity Object', 'Entity Object', null, null, 'uml entity object'), 1768 this.createVertexTemplateEntry('ellipse;shape=umlControl;whiteSpace=wrap;html=1;', 70, 80, 'Control Object', 'Control Object', null, null, 'uml control object'), 1769 this.createVertexTemplateEntry('shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;', 30, 60, 'Actor', 'Actor', false, null, 'uml actor'), 1770 this.createVertexTemplateEntry('ellipse;whiteSpace=wrap;html=1;', 140, 70, 'Use Case', 'Use Case', null, null, 'uml use case usecase'), 1771 this.addEntry('uml activity state start', function() 1772 { 1773 var cell = new mxCell('', new mxGeometry(0, 0, 30, 30), 1774 'ellipse;html=1;shape=startState;fillColor=#000000;strokeColor=#ff0000;'); 1775 cell.vertex = true; 1776 1777 var edge = new mxCell('', new mxGeometry(0, 0, 0, 0), 'edgeStyle=orthogonalEdgeStyle;html=1;verticalAlign=bottom;endArrow=open;endSize=8;strokeColor=#ff0000;'); 1778 edge.geometry.setTerminalPoint(new mxPoint(15, 90), false); 1779 edge.geometry.relative = true; 1780 edge.edge = true; 1781 1782 cell.insertEdge(edge, true); 1783 1784 return sb.createVertexTemplateFromCells([cell, edge], 30, 90, 'Start'); 1785 }), 1786 this.addEntry('uml activity state', function() 1787 { 1788 var cell = new mxCell('Activity', new mxGeometry(0, 0, 120, 40), 1789 'rounded=1;whiteSpace=wrap;html=1;arcSize=40;fontColor=#000000;fillColor=#ffffc0;strokeColor=#ff0000;'); 1790 cell.vertex = true; 1791 1792 var edge = new mxCell('', new mxGeometry(0, 0, 0, 0), 'edgeStyle=orthogonalEdgeStyle;html=1;verticalAlign=bottom;endArrow=open;endSize=8;strokeColor=#ff0000;'); 1793 edge.geometry.setTerminalPoint(new mxPoint(60, 100), false); 1794 edge.geometry.relative = true; 1795 edge.edge = true; 1796 1797 cell.insertEdge(edge, true); 1798 1799 return sb.createVertexTemplateFromCells([cell, edge], 120, 100, 'Activity'); 1800 }), 1801 this.addEntry('uml activity composite state', function() 1802 { 1803 var cell = new mxCell('Composite State', new mxGeometry(0, 0, 160, 60), 1804 'swimlane;fontStyle=1;align=center;verticalAlign=middle;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=0;resizeLast=1;container=0;fontColor=#000000;collapsible=0;rounded=1;arcSize=30;strokeColor=#ff0000;fillColor=#ffffc0;swimlaneFillColor=#ffffc0;dropTarget=0;'); 1805 cell.vertex = true; 1806 1807 var cell1 = new mxCell('Subtitle', new mxGeometry(0, 0, 200, 26), 'text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;spacingLeft=4;spacingRight=4;whiteSpace=wrap;overflow=hidden;rotatable=0;fontColor=#000000;'); 1808 cell1.vertex = true; 1809 cell.insert(cell1); 1810 1811 var edge = new mxCell('', new mxGeometry(0, 0, 0, 0), 'edgeStyle=orthogonalEdgeStyle;html=1;verticalAlign=bottom;endArrow=open;endSize=8;strokeColor=#ff0000;'); 1812 edge.geometry.setTerminalPoint(new mxPoint(80, 120), false); 1813 edge.geometry.relative = true; 1814 edge.edge = true; 1815 1816 cell.insertEdge(edge, true); 1817 1818 return sb.createVertexTemplateFromCells([cell, edge], 160, 120, 'Composite State'); 1819 }), 1820 this.addEntry('uml activity condition', function() 1821 { 1822 var cell = new mxCell('Condition', new mxGeometry(0, 0, 80, 40), 'rhombus;whiteSpace=wrap;html=1;fillColor=#ffffc0;strokeColor=#ff0000;'); 1823 cell.vertex = true; 1824 1825 var edge1 = new mxCell('no', new mxGeometry(0, 0, 0, 0), 'edgeStyle=orthogonalEdgeStyle;html=1;align=left;verticalAlign=bottom;endArrow=open;endSize=8;strokeColor=#ff0000;'); 1826 edge1.geometry.setTerminalPoint(new mxPoint(180, 20), false); 1827 edge1.geometry.relative = true; 1828 edge1.geometry.x = -1; 1829 edge1.edge = true; 1830 1831 cell.insertEdge(edge1, true); 1832 1833 var edge2 = new mxCell('yes', new mxGeometry(0, 0, 0, 0), 'edgeStyle=orthogonalEdgeStyle;html=1;align=left;verticalAlign=top;endArrow=open;endSize=8;strokeColor=#ff0000;'); 1834 edge2.geometry.setTerminalPoint(new mxPoint(40, 100), false); 1835 edge2.geometry.relative = true; 1836 edge2.geometry.x = -1; 1837 edge2.edge = true; 1838 1839 cell.insertEdge(edge2, true); 1840 1841 return sb.createVertexTemplateFromCells([cell, edge1, edge2], 180, 100, 'Condition'); 1842 }), 1843 this.addEntry('uml activity fork join', function() 1844 { 1845 var cell = new mxCell('', new mxGeometry(0, 0, 200, 10), 'shape=line;html=1;strokeWidth=6;strokeColor=#ff0000;'); 1846 cell.vertex = true; 1847 1848 var edge = new mxCell('', new mxGeometry(0, 0, 0, 0), 'edgeStyle=orthogonalEdgeStyle;html=1;verticalAlign=bottom;endArrow=open;endSize=8;strokeColor=#ff0000;'); 1849 edge.geometry.setTerminalPoint(new mxPoint(100, 80), false); 1850 edge.geometry.relative = true; 1851 edge.edge = true; 1852 1853 cell.insertEdge(edge, true); 1854 1855 return sb.createVertexTemplateFromCells([cell, edge], 200, 80, 'Fork/Join'); 1856 }), 1857 this.createVertexTemplateEntry('ellipse;html=1;shape=endState;fillColor=#000000;strokeColor=#ff0000;', 30, 30, '', 'End', null, null, 'uml activity state end'), 1858 this.createVertexTemplateEntry('shape=umlLifeline;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;collapsible=0;recursiveResize=0;outlineConnect=0;', 100, 300, ':Object', 'Lifeline', null, null, 'uml sequence participant lifeline'), 1859 this.createVertexTemplateEntry('shape=umlLifeline;participant=umlActor;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;collapsible=0;recursiveResize=0;verticalAlign=top;spacingTop=36;outlineConnect=0;', 1860 20, 300, '', 'Actor Lifeline', null, null, 'uml sequence participant lifeline actor'), 1861 this.createVertexTemplateEntry('shape=umlLifeline;participant=umlBoundary;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;collapsible=0;recursiveResize=0;verticalAlign=top;spacingTop=36;outlineConnect=0;', 1862 50, 300, '', 'Boundary Lifeline', null, null, 'uml sequence participant lifeline boundary'), 1863 this.createVertexTemplateEntry('shape=umlLifeline;participant=umlEntity;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;collapsible=0;recursiveResize=0;verticalAlign=top;spacingTop=36;outlineConnect=0;', 1864 40, 300, '', 'Entity Lifeline', null, null, 'uml sequence participant lifeline entity'), 1865 this.createVertexTemplateEntry('shape=umlLifeline;participant=umlControl;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;collapsible=0;recursiveResize=0;verticalAlign=top;spacingTop=36;outlineConnect=0;', 1866 40, 300, '', 'Control Lifeline', null, null, 'uml sequence participant lifeline control'), 1867 this.createVertexTemplateEntry('shape=umlFrame;whiteSpace=wrap;html=1;', 300, 200, 'frame', 'Frame', null, null, 'uml sequence frame'), 1868 this.createVertexTemplateEntry('shape=umlDestroy;whiteSpace=wrap;html=1;strokeWidth=3;', 30, 30, '', 'Destruction', null, null, 'uml sequence destruction destroy'), 1869 this.addEntry('uml sequence invoke invocation call activation', function() 1870 { 1871 var cell = new mxCell('', new mxGeometry(0, 0, 10, 80), 'html=1;points=[];perimeter=orthogonalPerimeter;'); 1872 cell.vertex = true; 1873 1874 var edge = new mxCell('dispatch', new mxGeometry(0, 0, 0, 0), 'html=1;verticalAlign=bottom;startArrow=oval;endArrow=block;startSize=8;'); 1875 edge.geometry.setTerminalPoint(new mxPoint(-60, 0), true); 1876 edge.geometry.relative = true; 1877 edge.edge = true; 1878 1879 cell.insertEdge(edge, false); 1880 1881 return sb.createVertexTemplateFromCells([cell, edge], 10, 80, 'Found Message'); 1882 }), 1883 this.addEntry('uml sequence invoke call delegation synchronous invocation activation', function() 1884 { 1885 var cell = new mxCell('', new mxGeometry(0, 0, 10, 80), 'html=1;points=[];perimeter=orthogonalPerimeter;'); 1886 cell.vertex = true; 1887 1888 var edge1 = new mxCell('dispatch', new mxGeometry(0, 0, 0, 0), 'html=1;verticalAlign=bottom;endArrow=block;entryX=0;entryY=0;'); 1889 edge1.geometry.setTerminalPoint(new mxPoint(-70, 0), true); 1890 edge1.geometry.relative = true; 1891 edge1.edge = true; 1892 1893 cell.insertEdge(edge1, false); 1894 1895 var edge2 = new mxCell('return', new mxGeometry(0, 0, 0, 0), 'html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;exitX=0;exitY=0.95;'); 1896 edge2.geometry.setTerminalPoint(new mxPoint(-70, 76), false); 1897 edge2.geometry.relative = true; 1898 edge2.edge = true; 1899 1900 cell.insertEdge(edge2, true); 1901 1902 return sb.createVertexTemplateFromCells([cell, edge1, edge2], 10, 80, 'Synchronous Invocation'); 1903 }), 1904 this.addEntry('uml sequence self call recursion delegation activation', function() 1905 { 1906 var cell = new mxCell('', new mxGeometry(-5, 20, 10, 40), 'html=1;points=[];perimeter=orthogonalPerimeter;'); 1907 cell.vertex = true; 1908 1909 var edge = new mxCell('self call', new mxGeometry(0, 0, 0, 0), 'edgeStyle=orthogonalEdgeStyle;html=1;align=left;spacingLeft=2;endArrow=block;rounded=0;entryX=1;entryY=0;'); 1910 edge.geometry.setTerminalPoint(new mxPoint(0, 0), true); 1911 edge.geometry.points = [new mxPoint(30, 0)]; 1912 edge.geometry.relative = true; 1913 edge.edge = true; 1914 1915 cell.insertEdge(edge, false); 1916 1917 return sb.createVertexTemplateFromCells([cell, edge], 10, 60, 'Self Call'); 1918 }), 1919 this.addEntry('uml sequence invoke call delegation callback activation', function() 1920 { 1921 // TODO: Check if more entries should be converted to compressed XML 1922 return sb.createVertexTemplateFromData('xZRNT8MwDIZ/Ta6oaymD47rBTkiTuMAxW6wmIm0q19s6fj1OE3V0Y2iCA4dK8euP2I+riGxedUuUjX52CqzIHkU2R+conKpuDtaKNDFKZAuRpgl/In264J303qSRCDVdk5CGhJ20WwhKEFo62ChoqritxURkReNMTa2X80LkC68AmgoIkEWHpF3pamlXR7WIFwASdBeb7KXY4RIc5+KBQ/ZGkY4RYY5Egyl1zLqLmmyDXQ6Zx4n5EIf+HkB2BmAjrV3LzftPIPw4hgNn1pQ1a2tH5Cp2QK1miG7vNeu4iJe4pdeY2BtvbCQDGlAljMCQxBJotJ8rWCFYSWY3LvUdmZi68rvkkLiU6QnL1m1xAzHoBOdw61WEb88II9AW67/ydQ2wq1Cy1aAGvOrFfPh6997qDA3g+dxzv3nIL6MPU/8T+kMw8+m4QPgdfrEJNo8PSQj/+s58Ag==', 1923 10, 60, 'Callback'); 1924 }), 1925 this.createVertexTemplateEntry('html=1;points=[];perimeter=orthogonalPerimeter;', 10, 80, '', 'Activation', null, null, 'uml sequence activation'), 1926 1927 this.createEdgeTemplateEntry('html=1;verticalAlign=bottom;startArrow=oval;startFill=1;endArrow=block;startSize=8;', 60, 0, 'dispatch', 'Found Message 1', null, 'uml sequence message call invoke dispatch'), 1928 this.createEdgeTemplateEntry('html=1;verticalAlign=bottom;startArrow=circle;startFill=1;endArrow=open;startSize=6;endSize=8;', 80, 0, 'dispatch', 'Found Message 2', null, 'uml sequence message call invoke dispatch'), 1929 this.createEdgeTemplateEntry('html=1;verticalAlign=bottom;endArrow=block;', 80, 0, 'dispatch', 'Message', null, 'uml sequence message call invoke dispatch'), 1930 this.addEntry('uml sequence return message', function() 1931 { 1932 var edge = new mxCell('return', new mxGeometry(0, 0, 0, 0), 'html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;'); 1933 edge.geometry.setTerminalPoint(new mxPoint(80, 0), true); 1934 edge.geometry.setTerminalPoint(new mxPoint(0, 0), false); 1935 edge.geometry.relative = true; 1936 edge.edge = true; 1937 1938 return sb.createEdgeTemplateFromCells([edge], 80, 0, 'Return'); 1939 }), 1940 this.addEntry('uml relation', function() 1941 { 1942 var edge = new mxCell('name', new mxGeometry(0, 0, 0, 0), 'endArrow=block;endFill=1;html=1;edgeStyle=orthogonalEdgeStyle;align=left;verticalAlign=top;'); 1943 edge.geometry.setTerminalPoint(new mxPoint(0, 0), true); 1944 edge.geometry.setTerminalPoint(new mxPoint(160, 0), false); 1945 edge.geometry.relative = true; 1946 edge.geometry.x = -1; 1947 edge.edge = true; 1948 1949 var cell = new mxCell('1', new mxGeometry(-1, 0, 0, 0), 'edgeLabel;resizable=0;html=1;align=left;verticalAlign=bottom;'); 1950 cell.geometry.relative = true; 1951 cell.setConnectable(false); 1952 cell.vertex = true; 1953 edge.insert(cell); 1954 1955 return sb.createEdgeTemplateFromCells([edge], 160, 0, 'Relation 1'); 1956 }), 1957 this.addEntry('uml association', function() 1958 { 1959 var edge = new mxCell('', new mxGeometry(0, 0, 0, 0), 'endArrow=none;html=1;edgeStyle=orthogonalEdgeStyle;'); 1960 edge.geometry.setTerminalPoint(new mxPoint(0, 0), true); 1961 edge.geometry.setTerminalPoint(new mxPoint(160, 0), false); 1962 edge.geometry.relative = true; 1963 edge.edge = true; 1964 1965 var cell1 = new mxCell('parent', new mxGeometry(-1, 0, 0, 0), 'edgeLabel;resizable=0;html=1;align=left;verticalAlign=bottom;'); 1966 cell1.geometry.relative = true; 1967 cell1.setConnectable(false); 1968 cell1.vertex = true; 1969 edge.insert(cell1); 1970 1971 var cell2 = new mxCell('child', new mxGeometry(1, 0, 0, 0), 'edgeLabel;resizable=0;html=1;align=right;verticalAlign=bottom;'); 1972 cell2.geometry.relative = true; 1973 cell2.setConnectable(false); 1974 cell2.vertex = true; 1975 edge.insert(cell2); 1976 1977 return sb.createEdgeTemplateFromCells([edge], 160, 0, 'Association 1'); 1978 }), 1979 this.addEntry('uml aggregation', function() 1980 { 1981 var edge = new mxCell('1', new mxGeometry(0, 0, 0, 0), 'endArrow=open;html=1;endSize=12;startArrow=diamondThin;startSize=14;startFill=0;edgeStyle=orthogonalEdgeStyle;align=left;verticalAlign=bottom;'); 1982 edge.geometry.setTerminalPoint(new mxPoint(0, 0), true); 1983 edge.geometry.setTerminalPoint(new mxPoint(160, 0), false); 1984 edge.geometry.relative = true; 1985 edge.geometry.x = -1; 1986 edge.geometry.y = 3; 1987 edge.edge = true; 1988 1989 return sb.createEdgeTemplateFromCells([edge], 160, 0, 'Aggregation 1'); 1990 }), 1991 this.addEntry('uml composition', function() 1992 { 1993 var edge = new mxCell('1', new mxGeometry(0, 0, 0, 0), 'endArrow=open;html=1;endSize=12;startArrow=diamondThin;startSize=14;startFill=1;edgeStyle=orthogonalEdgeStyle;align=left;verticalAlign=bottom;'); 1994 edge.geometry.setTerminalPoint(new mxPoint(0, 0), true); 1995 edge.geometry.setTerminalPoint(new mxPoint(160, 0), false); 1996 edge.geometry.relative = true; 1997 edge.geometry.x = -1; 1998 edge.geometry.y = 3; 1999 edge.edge = true; 2000 2001 return sb.createEdgeTemplateFromCells([edge], 160, 0, 'Composition 1'); 2002 }), 2003 this.addEntry('uml relation', function() 2004 { 2005 var edge = new mxCell('Relation', new mxGeometry(0, 0, 0, 0), 'endArrow=open;html=1;endSize=12;startArrow=diamondThin;startSize=14;startFill=0;edgeStyle=orthogonalEdgeStyle;'); 2006 edge.geometry.setTerminalPoint(new mxPoint(0, 0), true); 2007 edge.geometry.setTerminalPoint(new mxPoint(160, 0), false); 2008 edge.geometry.relative = true; 2009 edge.edge = true; 2010 2011 var cell1 = new mxCell('0..n', new mxGeometry(-1, 0, 0, 0), 'edgeLabel;resizable=0;html=1;align=left;verticalAlign=top;'); 2012 cell1.geometry.relative = true; 2013 cell1.setConnectable(false); 2014 cell1.vertex = true; 2015 edge.insert(cell1); 2016 2017 var cell2 = new mxCell('1', new mxGeometry(1, 0, 0, 0), 'edgeLabel;resizable=0;html=1;align=right;verticalAlign=top;'); 2018 cell2.geometry.relative = true; 2019 cell2.setConnectable(false); 2020 cell2.vertex = true; 2021 edge.insert(cell2); 2022 2023 return sb.createEdgeTemplateFromCells([edge], 160, 0, 'Relation 2'); 2024 }), 2025 this.createEdgeTemplateEntry('endArrow=open;endSize=12;dashed=1;html=1;', 160, 0, 'Use', 'Dependency', null, 'uml dependency use'), 2026 this.createEdgeTemplateEntry('endArrow=block;endSize=16;endFill=0;html=1;', 160, 0, 'Extends', 'Generalization', null, 'uml generalization extend'), 2027 this.createEdgeTemplateEntry('endArrow=block;startArrow=block;endFill=1;startFill=1;html=1;', 160, 0, '', 'Association 2', null, 'uml association'), 2028 this.createEdgeTemplateEntry('endArrow=open;startArrow=circlePlus;endFill=0;startFill=0;endSize=8;html=1;', 160, 0, '', 'Inner Class', null, 'uml inner class'), 2029 this.createEdgeTemplateEntry('endArrow=open;startArrow=cross;endFill=0;startFill=0;endSize=8;startSize=10;html=1;', 160, 0, '', 'Terminate', null, 'uml terminate'), 2030 this.createEdgeTemplateEntry('endArrow=block;dashed=1;endFill=0;endSize=12;html=1;', 160, 0, '', 'Implementation', null, 'uml realization implementation'), 2031 this.createEdgeTemplateEntry('endArrow=diamondThin;endFill=0;endSize=24;html=1;', 160, 0, '', 'Aggregation 2', null, 'uml aggregation'), 2032 this.createEdgeTemplateEntry('endArrow=diamondThin;endFill=1;endSize=24;html=1;', 160, 0, '', 'Composition 2', null, 'uml composition'), 2033 this.createEdgeTemplateEntry('endArrow=open;endFill=1;endSize=12;html=1;', 160, 0, '', 'Association 3', null, 'uml association') 2034 ]; 2035 2036 this.addPaletteFunctions('uml', mxResources.get('uml'), expand || false, fns); 2037 this.setCurrentSearchEntryLibrary(); 2038}; 2039 2040/** 2041 * Creates and returns the given title element. 2042 */ 2043Sidebar.prototype.createTitle = function(label) 2044{ 2045 var elt = document.createElement('a'); 2046 elt.setAttribute('title', mxResources.get('sidebarTooltip')); 2047 elt.className = 'geTitle'; 2048 mxUtils.write(elt, label); 2049 2050 return elt; 2051}; 2052 2053/** 2054 * Creates a thumbnail for the given cells. 2055 */ 2056Sidebar.prototype.createThumb = function(cells, width, height, parent, title, showLabel, showTitle) 2057{ 2058 this.graph.labelsVisible = (showLabel == null || showLabel); 2059 var fo = mxClient.NO_FO; 2060 mxClient.NO_FO = Editor.prototype.originalNoForeignObject; 2061 this.graph.view.scaleAndTranslate(1, 0, 0); 2062 this.graph.addCells(cells); 2063 2064 var bounds = this.graph.getGraphBounds(); 2065 var s = Math.floor(Math.min((width - 2 * this.thumbBorder) / bounds.width, 2066 (height - 2 * this.thumbBorder) / bounds.height) * 100) / 100; 2067 this.graph.view.scaleAndTranslate(s, Math.floor((width - bounds.width * s) / 2 / s - bounds.x), 2068 Math.floor((height - bounds.height * s) / 2 / s - bounds.y)); 2069 var node = null; 2070 2071 // For supporting HTML labels in IE9 standards mode the container is cloned instead 2072 if (this.graph.dialect == mxConstants.DIALECT_SVG && !mxClient.NO_FO && 2073 this.graph.view.getCanvas().ownerSVGElement != null) 2074 { 2075 node = this.graph.view.getCanvas().ownerSVGElement.cloneNode(true); 2076 } 2077 // LATER: Check if deep clone can be used for quirks if container in DOM 2078 else 2079 { 2080 node = this.graph.container.cloneNode(false); 2081 node.innerHTML = this.graph.container.innerHTML; 2082 } 2083 2084 this.graph.getModel().clear(); 2085 mxClient.NO_FO = fo; 2086 2087 node.style.position = 'relative'; 2088 node.style.overflow = 'hidden'; 2089 node.style.left = this.thumbBorder + 'px'; 2090 node.style.top = this.thumbBorder + 'px'; 2091 node.style.width = width + 'px'; 2092 node.style.height = height + 'px'; 2093 node.style.visibility = ''; 2094 node.style.minWidth = ''; 2095 node.style.minHeight = ''; 2096 2097 parent.appendChild(node); 2098 2099 // Adds title for sidebar entries 2100 if (this.sidebarTitles && title != null && showTitle != false) 2101 { 2102 var border = 0; 2103 parent.style.height = (this.thumbHeight + border + this.sidebarTitleSize + 8) + 'px'; 2104 2105 var div = document.createElement('div'); 2106 div.style.color = Editor.isDarkMode() ? '#A0A0A0' : '#303030'; 2107 div.style.fontSize = this.sidebarTitleSize + 'px'; 2108 div.style.textAlign = 'center'; 2109 div.style.whiteSpace = 'nowrap'; 2110 div.style.overflow = 'hidden'; 2111 div.style.textOverflow = 'ellipsis'; 2112 2113 if (mxClient.IS_IE) 2114 { 2115 div.style.height = (this.sidebarTitleSize + 12) + 'px'; 2116 } 2117 2118 div.style.paddingTop = '4px'; 2119 mxUtils.write(div, title); 2120 parent.appendChild(div); 2121 } 2122 2123 return bounds; 2124}; 2125 2126/** 2127 * Returns a function that creates a title. 2128 */ 2129Sidebar.prototype.createSection = function(title) 2130{ 2131 return mxUtils.bind(this, function() 2132 { 2133 var elt = document.createElement('div'); 2134 elt.setAttribute('title', title); 2135 elt.style.textOverflow = 'ellipsis'; 2136 elt.style.whiteSpace = 'nowrap'; 2137 elt.style.textAlign = 'center'; 2138 elt.style.overflow = 'hidden'; 2139 elt.style.width = '100%'; 2140 elt.style.padding = '14px 0'; 2141 2142 mxUtils.write(elt, title); 2143 2144 return elt; 2145 }); 2146}; 2147 2148/** 2149 * Creates and returns a new palette item for the given image. 2150 */ 2151Sidebar.prototype.createItem = function(cells, title, showLabel, showTitle, width, height, allowCellsInserted, showTooltip) 2152{ 2153 showTooltip = (showTooltip != null) ? showTooltip : true; 2154 2155 var elt = document.createElement('a'); 2156 elt.className = 'geItem'; 2157 elt.style.overflow = 'hidden'; 2158 var border = 2 * this.thumbBorder; 2159 elt.style.width = (this.thumbWidth + border) + 'px'; 2160 elt.style.height = (this.thumbHeight + border) + 'px'; 2161 elt.style.padding = this.thumbPadding + 'px'; 2162 2163 // Blocks default click action 2164 mxEvent.addListener(elt, 'click', function(evt) 2165 { 2166 mxEvent.consume(evt); 2167 }); 2168 2169 // Applies default styles 2170 var originalCells = cells; 2171 cells = this.graph.cloneCells(cells); 2172 this.editorUi.insertHandler(originalCells, null, this.graph.model, 2173 this.editorUi.editor.graph.defaultVertexStyle, 2174 this.editorUi.editor.graph.defaultEdgeStyle, 2175 true, true); 2176 2177 this.createThumb(originalCells, this.thumbWidth, this.thumbHeight, 2178 elt, title, showLabel, showTitle, width, height); 2179 var bounds = new mxRectangle(0, 0, width, height); 2180 2181 if (cells.length > 1 || cells[0].vertex) 2182 { 2183 var ds = this.createDragSource(elt, this.createDropHandler(cells, true, allowCellsInserted, 2184 bounds), this.createDragPreview(width, height), cells, bounds); 2185 this.addClickHandler(elt, ds, cells); 2186 2187 // Uses guides for vertices only if enabled in graph 2188 ds.isGuidesEnabled = mxUtils.bind(this, function() 2189 { 2190 return this.editorUi.editor.graph.graphHandler.guidesEnabled; 2191 }); 2192 } 2193 else if (cells[0] != null && cells[0].edge) 2194 { 2195 var ds = this.createDragSource(elt, this.createDropHandler(cells, false, allowCellsInserted, 2196 bounds), this.createDragPreview(width, height), cells, bounds); 2197 this.addClickHandler(elt, ds, cells); 2198 } 2199 2200 // Shows a tooltip with the rendered cell 2201 if (!mxClient.IS_IOS && showTooltip) 2202 { 2203 mxEvent.addGestureListeners(elt, null, mxUtils.bind(this, function(evt) 2204 { 2205 if (mxEvent.isMouseEvent(evt)) 2206 { 2207 this.showTooltip(elt, cells, bounds.width, bounds.height, title, showLabel); 2208 } 2209 })); 2210 } 2211 2212 return elt; 2213}; 2214 2215/** 2216 * Creates a drop handler for inserting the given cells. 2217 */ 2218Sidebar.prototype.updateShapes = function(source, targets) 2219{ 2220 var graph = this.editorUi.editor.graph; 2221 var sourceCellStyle = graph.getCellStyle(source); 2222 var result = []; 2223 2224 graph.model.beginUpdate(); 2225 try 2226 { 2227 var cellStyle = graph.getModel().getStyle(source); 2228 2229 // Lists the styles to carry over from the existing shape 2230 var styles = ['shadow', 'dashed', 'dashPattern', 'fontFamily', 'fontSize', 'fontColor', 'align', 'startFill', 2231 'startSize', 'endFill', 'endSize', 'strokeColor', 'strokeWidth', 'fillColor', 'gradientColor', 2232 'html', 'part', 'noEdgeStyle', 'edgeStyle', 'elbow', 'childLayout', 'recursiveResize', 2233 'container', 'collapsible', 'connectable', 'comic', 'sketch', 'fillWeight', 'hachureGap', 2234 'hachureAngle', 'jiggle', 'disableMultiStroke', 'disableMultiStrokeFill', 2235 'fillStyle', 'curveFitting', 'simplification', 'sketchStyle']; 2236 2237 for (var i = 0; i < targets.length; i++) 2238 { 2239 var targetCell = targets[i]; 2240 2241 if ((graph.getModel().isVertex(targetCell) == graph.getModel().isVertex(source)) || 2242 (graph.getModel().isEdge(targetCell) == graph.getModel().isEdge(source))) 2243 { 2244 var style = graph.getCurrentCellStyle(targets[i]); 2245 graph.getModel().setStyle(targetCell, cellStyle); 2246 2247 // Removes all children of composite cells 2248 if (mxUtils.getValue(style, 'composite', '0') == '1') 2249 { 2250 var childCount = graph.model.getChildCount(targetCell); 2251 2252 for (var j = childCount; j >= 0; j--) 2253 { 2254 graph.model.remove(graph.model.getChildAt(targetCell, j)); 2255 } 2256 } 2257 2258 // Replaces the participant style in the lifeline shape with the target shape 2259 if (style[mxConstants.STYLE_SHAPE] == 'umlLifeline' && 2260 sourceCellStyle[mxConstants.STYLE_SHAPE] != 'umlLifeline') 2261 { 2262 graph.setCellStyles(mxConstants.STYLE_SHAPE, 'umlLifeline', [targetCell]); 2263 graph.setCellStyles('participant', sourceCellStyle[mxConstants.STYLE_SHAPE], [targetCell]); 2264 } 2265 2266 for (var j = 0; j < styles.length; j++) 2267 { 2268 var value = style[styles[j]]; 2269 2270 if (value != null) 2271 { 2272 graph.setCellStyles(styles[j], value, [targetCell]); 2273 } 2274 } 2275 2276 result.push(targetCell); 2277 } 2278 } 2279 } 2280 finally 2281 { 2282 graph.model.endUpdate(); 2283 } 2284 2285 return result; 2286}; 2287 2288/** 2289 * Creates a drop handler for inserting the given cells. 2290 */ 2291Sidebar.prototype.createDropHandler = function(cells, allowSplit, allowCellsInserted, bounds) 2292{ 2293 allowCellsInserted = (allowCellsInserted != null) ? allowCellsInserted : true; 2294 2295 return mxUtils.bind(this, function(graph, evt, target, x, y, force) 2296 { 2297 var elt = (force) ? null : ((mxEvent.isTouchEvent(evt) || mxEvent.isPenEvent(evt)) ? 2298 document.elementFromPoint(mxEvent.getClientX(evt), mxEvent.getClientY(evt)) : 2299 mxEvent.getSource(evt)); 2300 2301 while (elt != null && elt != this.container) 2302 { 2303 elt = elt.parentNode; 2304 } 2305 2306 if (elt == null && graph.isEnabled()) 2307 { 2308 cells = graph.getImportableCells(cells); 2309 2310 if (cells.length > 0) 2311 { 2312 graph.stopEditing(); 2313 2314 // Holding alt while mouse is released ignores drop target 2315 var validDropTarget = (target != null && !mxEvent.isAltDown(evt)) ? 2316 graph.isValidDropTarget(target, cells, evt) : false; 2317 2318 var select = null; 2319 2320 if (target != null && !validDropTarget) 2321 { 2322 target = null; 2323 } 2324 2325 if (!graph.isCellLocked(target || graph.getDefaultParent())) 2326 { 2327 graph.model.beginUpdate(); 2328 try 2329 { 2330 x = Math.round(x); 2331 y = Math.round(y); 2332 2333 // Splits the target edge or inserts into target group 2334 if (allowSplit && graph.isSplitTarget(target, cells, evt)) 2335 { 2336 var s = graph.view.scale; 2337 var tr = graph.view.translate; 2338 var tx = (x + tr.x) * s; 2339 var ty = (y + tr.y) * s; 2340 2341 var clones = graph.cloneCells(cells); 2342 graph.splitEdge(target, clones, null, 2343 x - bounds.width / 2, y - bounds.height / 2, 2344 tx, ty); 2345 select = clones; 2346 } 2347 else if (cells.length > 0) 2348 { 2349 select = graph.importCells(cells, x, y, target); 2350 } 2351 2352 // Executes parent layout hooks for position/order 2353 if (graph.layoutManager != null) 2354 { 2355 var layout = graph.layoutManager.getLayout(target); 2356 2357 if (layout != null) 2358 { 2359 var s = graph.view.scale; 2360 var tr = graph.view.translate; 2361 var tx = (x + tr.x) * s; 2362 var ty = (y + tr.y) * s; 2363 2364 for (var i = 0; i < select.length; i++) 2365 { 2366 layout.moveCell(select[i], tx, ty); 2367 } 2368 } 2369 } 2370 2371 if (allowCellsInserted && (evt == null || !mxEvent.isShiftDown(evt))) 2372 { 2373 graph.fireEvent(new mxEventObject('cellsInserted', 'cells', select)); 2374 } 2375 } 2376 catch (e) 2377 { 2378 this.editorUi.handleError(e); 2379 } 2380 finally 2381 { 2382 graph.model.endUpdate(); 2383 } 2384 2385 if (select != null && select.length > 0) 2386 { 2387 graph.scrollCellToVisible(select[0]); 2388 graph.setSelectionCells(select); 2389 } 2390 2391 if (graph.editAfterInsert && evt != null && mxEvent.isMouseEvent(evt) && 2392 select != null && select.length == 1) 2393 { 2394 window.setTimeout(function() 2395 { 2396 graph.startEditing(select[0]); 2397 }, 0); 2398 } 2399 } 2400 } 2401 2402 mxEvent.consume(evt); 2403 } 2404 }); 2405}; 2406 2407/** 2408 * Creates and returns a preview element for the given width and height. 2409 */ 2410Sidebar.prototype.createDragPreview = function(width, height) 2411{ 2412 var elt = document.createElement('div'); 2413 elt.className = 'geDragPreview'; 2414 elt.style.width = width + 'px'; 2415 elt.style.height = height + 'px'; 2416 2417 return elt; 2418}; 2419 2420/** 2421 * Creates a drag source for the given element. 2422 */ 2423Sidebar.prototype.dropAndConnect = function(source, targets, direction, dropCellIndex, evt) 2424{ 2425 var geo = this.getDropAndConnectGeometry(source, targets[dropCellIndex], direction, targets); 2426 2427 // Targets without the new edge for selection 2428 var tmp = []; 2429 2430 if (geo != null) 2431 { 2432 var graph = this.editorUi.editor.graph; 2433 var editingCell = null; 2434 2435 graph.model.beginUpdate(); 2436 try 2437 { 2438 var sourceGeo = graph.getCellGeometry(source); 2439 var geo2 = graph.getCellGeometry(targets[dropCellIndex]); 2440 2441 // Handles special case where target should be ignored for stack layouts 2442 var targetParent = graph.model.getParent(source); 2443 var validLayout = true; 2444 2445 // Ignores parent if it has a stack layout or if it is a table or row 2446 if (graph.layoutManager != null) 2447 { 2448 var layout = graph.layoutManager.getLayout(targetParent); 2449 2450 // LATER: Use parent of parent if valid layout 2451 if (layout != null && layout.constructor == mxStackLayout) 2452 { 2453 validLayout = false; 2454 } 2455 } 2456 2457 // Checks if another container is at the drop location 2458 var tmp = (graph.model.isEdge(source)) ? null : graph.view.getState(targetParent); 2459 var dx = 0; 2460 var dy = 0; 2461 2462 // Offsets by parent position 2463 if (tmp != null) 2464 { 2465 var offset = tmp.origin; 2466 dx = offset.x; 2467 dy = offset.y; 2468 2469 var pt = geo.getTerminalPoint(false); 2470 2471 if (pt != null) 2472 { 2473 pt.x += offset.x; 2474 pt.y += offset.y; 2475 } 2476 } 2477 2478 var useParent = !graph.isTableRow(source) && !graph.isTableCell(source) && 2479 (graph.model.isEdge(source) || (sourceGeo != null && 2480 !sourceGeo.relative && validLayout)); 2481 2482 var tempTarget = graph.getCellAt((geo.x + dx + graph.view.translate.x) * graph.view.scale, 2483 (geo.y + dy + graph.view.translate.y) * graph.view.scale, null, null, null, function(state, x, y) 2484 { 2485 return !graph.isContainer(state.cell); 2486 }); 2487 2488 if (tempTarget != null && tempTarget != targetParent) 2489 { 2490 tmp = graph.view.getState(tempTarget); 2491 2492 // Offsets by new parent position 2493 if (tmp != null) 2494 { 2495 var offset = tmp.origin; 2496 targetParent = tempTarget; 2497 useParent = true; 2498 2499 if (!graph.model.isEdge(source)) 2500 { 2501 geo.x -= offset.x - dx; 2502 geo.y -= offset.y - dy; 2503 } 2504 } 2505 } 2506 else if (!validLayout || graph.isTableRow(source) || graph.isTableCell(source)) 2507 { 2508 geo.x += dx; 2509 geo.y += dy; 2510 } 2511 2512 dx = geo2.x; 2513 dy = geo2.y; 2514 2515 // Ignores geometry of edges 2516 if (graph.model.isEdge(targets[dropCellIndex])) 2517 { 2518 dx = 0; 2519 dy = 0; 2520 } 2521 2522 targets = graph.importCells(targets, (geo.x - (useParent ? dx : 0)), 2523 (geo.y - (useParent ? dy : 0)), (useParent) ? targetParent : null); 2524 tmp = targets; 2525 2526 if (graph.model.isEdge(source)) 2527 { 2528 // Adds new terminal to edge 2529 // LATER: Push new terminal out radially from edge start point 2530 graph.model.setTerminal(source, targets[dropCellIndex], 2531 direction == mxConstants.DIRECTION_NORTH); 2532 } 2533 else if (graph.model.isEdge(targets[dropCellIndex])) 2534 { 2535 // Adds new outgoing connection to vertex and clears points 2536 graph.model.setTerminal(targets[dropCellIndex], source, true); 2537 var geo3 = graph.getCellGeometry(targets[dropCellIndex]); 2538 geo3.points = null; 2539 2540 if (geo3.getTerminalPoint(false) != null) 2541 { 2542 geo3.setTerminalPoint(geo.getTerminalPoint(false), false); 2543 } 2544 else if (useParent && graph.model.isVertex(targetParent)) 2545 { 2546 // Adds parent offset to other nodes 2547 var tmpState = graph.view.getState(targetParent); 2548 var offset = (tmpState.cell != graph.view.currentRoot) ? 2549 tmpState.origin : new mxPoint(0, 0); 2550 2551 graph.cellsMoved(targets, offset.x, offset.y, null, null, true); 2552 } 2553 } 2554 else 2555 { 2556 geo2 = graph.getCellGeometry(targets[dropCellIndex]); 2557 dx = geo.x - Math.round(geo2.x); 2558 dy = geo.y - Math.round(geo2.y); 2559 geo.x = Math.round(geo2.x); 2560 geo.y = Math.round(geo2.y); 2561 graph.model.setGeometry(targets[dropCellIndex], geo); 2562 graph.cellsMoved(targets, dx, dy, null, null, true); 2563 tmp = targets.slice(); 2564 editingCell = (tmp.length == 1) ? tmp[0] : null; 2565 targets.push(graph.insertEdge(null, null, '', source, targets[dropCellIndex], 2566 graph.createCurrentEdgeStyle())); 2567 } 2568 2569 if (evt == null || !mxEvent.isShiftDown(evt)) 2570 { 2571 graph.fireEvent(new mxEventObject('cellsInserted', 'cells', targets)); 2572 } 2573 } 2574 catch (e) 2575 { 2576 this.editorUi.handleError(e); 2577 } 2578 finally 2579 { 2580 graph.model.endUpdate(); 2581 } 2582 2583 if (graph.editAfterInsert && evt != null && mxEvent.isMouseEvent(evt) && 2584 editingCell != null) 2585 { 2586 window.setTimeout(function() 2587 { 2588 graph.startEditing(editingCell); 2589 }, 0); 2590 } 2591 } 2592 2593 return tmp; 2594}; 2595 2596/** 2597 * Creates a drag source for the given element. 2598 */ 2599Sidebar.prototype.getDropAndConnectGeometry = function(source, target, direction, targets) 2600{ 2601 var graph = this.editorUi.editor.graph; 2602 var view = graph.view; 2603 var keepSize = targets.length > 1; 2604 var geo = graph.getCellGeometry(source); 2605 var geo2 = graph.getCellGeometry(target); 2606 2607 if (geo != null && geo2 != null) 2608 { 2609 geo2 = geo2.clone(); 2610 2611 if (graph.model.isEdge(source)) 2612 { 2613 var state = graph.view.getState(source); 2614 var pts = state.absolutePoints; 2615 var p0 = pts[0]; 2616 var pe = pts[pts.length - 1]; 2617 2618 if (direction == mxConstants.DIRECTION_NORTH) 2619 { 2620 geo2.x = p0.x / view.scale - view.translate.x - geo2.width / 2; 2621 geo2.y = p0.y / view.scale - view.translate.y - geo2.height / 2; 2622 } 2623 else 2624 { 2625 geo2.x = pe.x / view.scale - view.translate.x - geo2.width / 2; 2626 geo2.y = pe.y / view.scale - view.translate.y - geo2.height / 2; 2627 } 2628 } 2629 else 2630 { 2631 if (geo.relative) 2632 { 2633 var state = graph.view.getState(source); 2634 geo = geo.clone(); 2635 geo.x = (state.x - view.translate.x) / view.scale; 2636 geo.y = (state.y - view.translate.y) / view.scale; 2637 } 2638 2639 var length = graph.defaultEdgeLength; 2640 2641 // Maintains edge length 2642 if (graph.model.isEdge(target) && geo2.getTerminalPoint(true) != null && 2643 geo2.getTerminalPoint(false) != null) 2644 { 2645 var p0 = geo2.getTerminalPoint(true); 2646 var pe = geo2.getTerminalPoint(false); 2647 var dx = pe.x - p0.x; 2648 var dy = pe.y - p0.y; 2649 2650 length = Math.sqrt(dx * dx + dy * dy); 2651 2652 geo2.x = geo.getCenterX(); 2653 geo2.y = geo.getCenterY(); 2654 geo2.width = 1; 2655 geo2.height = 1; 2656 2657 if (direction == mxConstants.DIRECTION_NORTH) 2658 { 2659 geo2.height = length 2660 geo2.y = geo.y - length; 2661 geo2.setTerminalPoint(new mxPoint(geo2.x, geo2.y), false); 2662 } 2663 else if (direction == mxConstants.DIRECTION_EAST) 2664 { 2665 geo2.width = length 2666 geo2.x = geo.x + geo.width; 2667 geo2.setTerminalPoint(new mxPoint(geo2.x + geo2.width, geo2.y), false); 2668 } 2669 else if (direction == mxConstants.DIRECTION_SOUTH) 2670 { 2671 geo2.height = length 2672 geo2.y = geo.y + geo.height; 2673 geo2.setTerminalPoint(new mxPoint(geo2.x, geo2.y + geo2.height), false); 2674 } 2675 else if (direction == mxConstants.DIRECTION_WEST) 2676 { 2677 geo2.width = length 2678 geo2.x = geo.x - length; 2679 geo2.setTerminalPoint(new mxPoint(geo2.x, geo2.y), false); 2680 } 2681 } 2682 else 2683 { 2684 // Try match size or ignore if width or height < 45 which 2685 // is considered special enough to be ignored here 2686 if (!keepSize && geo2.width > 45 && geo2.height > 45 && 2687 geo.width > 45 && geo.height > 45) 2688 { 2689 geo2.width = geo2.width * (geo.height / geo2.height); 2690 geo2.height = geo.height; 2691 } 2692 2693 geo2.x = geo.x + geo.width / 2 - geo2.width / 2; 2694 geo2.y = geo.y + geo.height / 2 - geo2.height / 2; 2695 2696 if (direction == mxConstants.DIRECTION_NORTH) 2697 { 2698 geo2.y = geo2.y - geo.height / 2 - geo2.height / 2 - length; 2699 } 2700 else if (direction == mxConstants.DIRECTION_EAST) 2701 { 2702 geo2.x = geo2.x + geo.width / 2 + geo2.width / 2 + length; 2703 } 2704 else if (direction == mxConstants.DIRECTION_SOUTH) 2705 { 2706 geo2.y = geo2.y + geo.height / 2 + geo2.height / 2 + length; 2707 } 2708 else if (direction == mxConstants.DIRECTION_WEST) 2709 { 2710 geo2.x = geo2.x - geo.width / 2 - geo2.width / 2 - length; 2711 } 2712 2713 // Adds offset to match cells without connecting edge 2714 if (graph.model.isEdge(target) && geo2.getTerminalPoint(true) != null && 2715 target.getTerminal(false) != null) 2716 { 2717 var targetGeo = graph.getCellGeometry(target.getTerminal(false)); 2718 2719 if (targetGeo != null) 2720 { 2721 if (direction == mxConstants.DIRECTION_NORTH) 2722 { 2723 geo2.x -= targetGeo.getCenterX(); 2724 geo2.y -= targetGeo.getCenterY() + targetGeo.height / 2; 2725 } 2726 else if (direction == mxConstants.DIRECTION_EAST) 2727 { 2728 geo2.x -= targetGeo.getCenterX() - targetGeo.width / 2; 2729 geo2.y -= targetGeo.getCenterY(); 2730 } 2731 else if (direction == mxConstants.DIRECTION_SOUTH) 2732 { 2733 geo2.x -= targetGeo.getCenterX(); 2734 geo2.y -= targetGeo.getCenterY() - targetGeo.height / 2; 2735 } 2736 else if (direction == mxConstants.DIRECTION_WEST) 2737 { 2738 geo2.x -= targetGeo.getCenterX() + targetGeo.width / 2; 2739 geo2.y -= targetGeo.getCenterY(); 2740 } 2741 } 2742 } 2743 } 2744 } 2745 } 2746 2747 return geo2; 2748}; 2749 2750/** 2751 * Limits drop style to non-transparent source shapes. 2752 */ 2753Sidebar.prototype.isDropStyleEnabled = function(cells, firstVertex) 2754{ 2755 var result = true; 2756 2757 if (firstVertex != null && cells.length == 1) 2758 { 2759 var vstyle = this.graph.getCellStyle(cells[firstVertex]); 2760 2761 if (vstyle != null) 2762 { 2763 result = mxUtils.getValue(vstyle, mxConstants.STYLE_STROKECOLOR, mxConstants.NONE) != mxConstants.NONE || 2764 mxUtils.getValue(vstyle, mxConstants.STYLE_FILLCOLOR, mxConstants.NONE) != mxConstants.NONE; 2765 } 2766 } 2767 2768 return result; 2769}; 2770 2771/** 2772 * Ignores swimlanes as drop style targets. 2773 */ 2774Sidebar.prototype.isDropStyleTargetIgnored = function(state) 2775{ 2776 return this.graph.isSwimlane(state.cell) || this.graph.isTableCell(state.cell) || 2777 this.graph.isTableRow(state.cell) || this.graph.isTable(state.cell); 2778}; 2779 2780/** 2781 * Creates a drag source for the given element. 2782 */ 2783Sidebar.prototype.createDragSource = function(elt, dropHandler, preview, cells, bounds) 2784{ 2785 // Checks if the cells contain any vertices 2786 var ui = this.editorUi; 2787 var graph = ui.editor.graph; 2788 var freeSourceEdge = null; 2789 var firstVertex = null; 2790 var sidebar = this; 2791 2792 for (var i = 0; i < cells.length; i++) 2793 { 2794 if (firstVertex == null && graph.model.isVertex(cells[i])) 2795 { 2796 firstVertex = i; 2797 } 2798 else if (freeSourceEdge == null && graph.model.isEdge(cells[i]) && 2799 graph.model.getTerminal(cells[i], true) == null) 2800 { 2801 freeSourceEdge = i; 2802 } 2803 2804 if (firstVertex != null && freeSourceEdge != null) 2805 { 2806 break; 2807 } 2808 } 2809 2810 var dropStyleEnabled = this.isDropStyleEnabled(cells, firstVertex); 2811 2812 var dragSource = mxUtils.makeDraggable(elt, graph, mxUtils.bind(this, function(graph, evt, target, x, y) 2813 { 2814 if (this.updateThread != null) 2815 { 2816 window.clearTimeout(this.updateThread); 2817 } 2818 2819 if (cells != null && currentStyleTarget != null && activeArrow == styleTarget) 2820 { 2821 var tmp = graph.isCellSelected(currentStyleTarget.cell) ? graph.getSelectionCells() : [currentStyleTarget.cell]; 2822 var updatedCells = this.updateShapes((graph.model.isEdge(currentStyleTarget.cell)) ? cells[0] : cells[firstVertex], tmp); 2823 graph.setSelectionCells(updatedCells); 2824 } 2825 else if (cells != null && activeArrow != null && currentTargetState != null && activeArrow != styleTarget) 2826 { 2827 var index = (graph.model.isEdge(currentTargetState.cell) || freeSourceEdge == null) ? firstVertex : freeSourceEdge; 2828 graph.setSelectionCells(this.dropAndConnect(currentTargetState.cell, cells, direction, index, evt)); 2829 } 2830 else 2831 { 2832 dropHandler.apply(this, arguments); 2833 } 2834 2835 if (this.editorUi.hoverIcons != null) 2836 { 2837 this.editorUi.hoverIcons.update(graph.view.getState(graph.getSelectionCell())); 2838 } 2839 }), preview, 0, 0, graph.autoscroll, true, true); 2840 2841 // Stops dragging if cancel is pressed 2842 graph.addListener(mxEvent.ESCAPE, function(sender, evt) 2843 { 2844 if (dragSource.isActive()) 2845 { 2846 dragSource.reset(); 2847 } 2848 }); 2849 2850 // Overrides mouseDown to ignore popup triggers 2851 var mouseDown = dragSource.mouseDown; 2852 2853 dragSource.mouseDown = function(evt) 2854 { 2855 if (!mxEvent.isPopupTrigger(evt) && !mxEvent.isMultiTouchEvent(evt) && 2856 !graph.isCellLocked(graph.getDefaultParent())) 2857 { 2858 graph.stopEditing(); 2859 mouseDown.apply(this, arguments); 2860 } 2861 }; 2862 2863 // Workaround for event redirection via image tag in quirks and IE8 2864 function createArrow(img, tooltip) 2865 { 2866 var arrow = null; 2867 arrow = mxUtils.createImage(img.src); 2868 arrow.style.width = img.width + 'px'; 2869 arrow.style.height = img.height + 'px'; 2870 2871 if (tooltip != null) 2872 { 2873 arrow.setAttribute('title', tooltip); 2874 } 2875 2876 mxUtils.setOpacity(arrow, (img == this.refreshTarget) ? 30 : 20); 2877 arrow.style.position = 'absolute'; 2878 arrow.style.cursor = 'crosshair'; 2879 2880 return arrow; 2881 }; 2882 2883 var currentTargetState = null; 2884 var currentStateHandle = null; 2885 var currentStyleTarget = null; 2886 var activeTarget = false; 2887 2888 var arrowUp = createArrow(this.triangleUp, mxResources.get('connect')); 2889 var arrowRight = createArrow(this.triangleRight, mxResources.get('connect')); 2890 var arrowDown = createArrow(this.triangleDown, mxResources.get('connect')); 2891 var arrowLeft = createArrow(this.triangleLeft, mxResources.get('connect')); 2892 var styleTarget = createArrow(this.refreshTarget, mxResources.get('replace')); 2893 // Workaround for actual parentNode not being updated in old IE 2894 var styleTargetParent = null; 2895 var roundSource = createArrow(this.roundDrop); 2896 var roundTarget = createArrow(this.roundDrop); 2897 var direction = mxConstants.DIRECTION_NORTH; 2898 var activeArrow = null; 2899 2900 function checkArrow(x, y, bounds, arrow) 2901 { 2902 if (arrow.parentNode != null) 2903 { 2904 if (mxUtils.contains(bounds, x, y)) 2905 { 2906 mxUtils.setOpacity(arrow, 100); 2907 activeArrow = arrow; 2908 } 2909 else 2910 { 2911 mxUtils.setOpacity(arrow, (arrow == styleTarget) ? 30 : 20); 2912 } 2913 } 2914 2915 return bounds; 2916 }; 2917 2918 // Hides guides and preview if target is active 2919 var dsCreatePreviewElement = dragSource.createPreviewElement; 2920 2921 // Stores initial size of preview element 2922 dragSource.createPreviewElement = function(graph) 2923 { 2924 var elt = dsCreatePreviewElement.apply(this, arguments); 2925 2926 // Pass-through events required to tooltip on replace shape 2927 if (mxClient.IS_SVG) 2928 { 2929 elt.style.pointerEvents = 'none'; 2930 } 2931 2932 this.previewElementWidth = elt.style.width; 2933 this.previewElementHeight = elt.style.height; 2934 2935 return elt; 2936 }; 2937 2938 // Shows/hides hover icons 2939 var dragEnter = dragSource.dragEnter; 2940 dragSource.dragEnter = function(graph, evt) 2941 { 2942 if (ui.hoverIcons != null) 2943 { 2944 ui.hoverIcons.setDisplay('none'); 2945 } 2946 2947 dragEnter.apply(this, arguments); 2948 }; 2949 2950 var dragExit = dragSource.dragExit; 2951 dragSource.dragExit = function(graph, evt) 2952 { 2953 if (ui.hoverIcons != null) 2954 { 2955 ui.hoverIcons.setDisplay(''); 2956 } 2957 2958 dragExit.apply(this, arguments); 2959 }; 2960 2961 dragSource.dragOver = function(graph, evt) 2962 { 2963 mxDragSource.prototype.dragOver.apply(this, arguments); 2964 2965 if (this.currentGuide != null && activeArrow != null) 2966 { 2967 this.currentGuide.hide(); 2968 } 2969 2970 if (this.previewElement != null) 2971 { 2972 var view = graph.view; 2973 2974 if (currentStyleTarget != null && activeArrow == styleTarget) 2975 { 2976 this.previewElement.style.display = (graph.model.isEdge(currentStyleTarget.cell)) ? 'none' : ''; 2977 2978 this.previewElement.style.left = currentStyleTarget.x + 'px'; 2979 this.previewElement.style.top = currentStyleTarget.y + 'px'; 2980 this.previewElement.style.width = currentStyleTarget.width + 'px'; 2981 this.previewElement.style.height = currentStyleTarget.height + 'px'; 2982 } 2983 else if (currentTargetState != null && activeArrow != null) 2984 { 2985 if (dragSource.currentHighlight != null && dragSource.currentHighlight.state != null) 2986 { 2987 dragSource.currentHighlight.hide(); 2988 } 2989 2990 var index = (graph.model.isEdge(currentTargetState.cell) || freeSourceEdge == null) ? firstVertex : freeSourceEdge; 2991 var geo = sidebar.getDropAndConnectGeometry(currentTargetState.cell, cells[index], direction, cells); 2992 var geo2 = (!graph.model.isEdge(currentTargetState.cell)) ? graph.getCellGeometry(currentTargetState.cell) : null; 2993 var geo3 = graph.getCellGeometry(cells[index]); 2994 var parent = graph.model.getParent(currentTargetState.cell); 2995 var dx = view.translate.x * view.scale; 2996 var dy = view.translate.y * view.scale; 2997 2998 if (geo2 != null && !geo2.relative && graph.model.isVertex(parent) && parent != view.currentRoot) 2999 { 3000 var pState = view.getState(parent); 3001 3002 dx = pState.x; 3003 dy = pState.y; 3004 } 3005 3006 var dx2 = geo3.x; 3007 var dy2 = geo3.y; 3008 3009 // Ignores geometry of edges 3010 if (graph.model.isEdge(cells[index])) 3011 { 3012 dx2 = 0; 3013 dy2 = 0; 3014 } 3015 3016 // Shows preview at drop location 3017 this.previewElement.style.left = ((geo.x - dx2) * view.scale + dx) + 'px'; 3018 this.previewElement.style.top = ((geo.y - dy2) * view.scale + dy) + 'px'; 3019 3020 if (cells.length == 1) 3021 { 3022 this.previewElement.style.width = (geo.width * view.scale) + 'px'; 3023 this.previewElement.style.height = (geo.height * view.scale) + 'px'; 3024 } 3025 3026 this.previewElement.style.display = ''; 3027 } 3028 else if (dragSource.currentHighlight.state != null && 3029 graph.model.isEdge(dragSource.currentHighlight.state.cell)) 3030 { 3031 // Centers drop cells when splitting edges 3032 this.previewElement.style.left = Math.round(parseInt(this.previewElement.style.left) - 3033 bounds.width * view.scale / 2) + 'px'; 3034 this.previewElement.style.top = Math.round(parseInt(this.previewElement.style.top) - 3035 bounds.height * view.scale / 2) + 'px'; 3036 } 3037 else 3038 { 3039 this.previewElement.style.width = this.previewElementWidth; 3040 this.previewElement.style.height = this.previewElementHeight; 3041 this.previewElement.style.display = ''; 3042 } 3043 } 3044 }; 3045 3046 var startTime = new Date().getTime(); 3047 var timeOnTarget = 0; 3048 var prev = null; 3049 3050 // Gets source cell style to compare shape below 3051 var sourceCellStyle = this.editorUi.editor.graph.getCellStyle(cells[0]); 3052 3053 // Allows drop into cell only if target is a valid root 3054 dragSource.getDropTarget = mxUtils.bind(this, function(graph, x, y, evt) 3055 { 3056 // Alt means no targets at all 3057 // LATER: Show preview where result will go 3058 var cell = (!mxEvent.isAltDown(evt) && cells != null) ? 3059 graph.getCellAt(x, y, null, null, null, function(state, x, y) 3060 { 3061 return graph.isContainer(state.cell); 3062 }) : null; 3063 3064 // Uses connectable parent vertex if one exists 3065 if (cell != null && !this.graph.isCellConnectable(cell) && 3066 !this.graph.model.isEdge(cell)) 3067 { 3068 var parent = this.graph.getModel().getParent(cell); 3069 3070 if (this.graph.getModel().isVertex(parent) && 3071 this.graph.isCellConnectable(parent)) 3072 { 3073 cell = parent; 3074 } 3075 } 3076 3077 // Ignores locked cells 3078 if (graph.isCellLocked(cell)) 3079 { 3080 cell = null; 3081 } 3082 3083 var state = graph.view.getState(cell); 3084 activeArrow = null; 3085 var bbox = null; 3086 3087 // Time on target 3088 if (prev != state) 3089 { 3090 startTime = new Date().getTime(); 3091 timeOnTarget = 0; 3092 prev = state; 3093 3094 if (this.updateThread != null) 3095 { 3096 window.clearTimeout(this.updateThread); 3097 } 3098 3099 if (state != null) 3100 { 3101 this.updateThread = window.setTimeout(function() 3102 { 3103 if (activeArrow == null) 3104 { 3105 prev = state; 3106 dragSource.getDropTarget(graph, x, y, evt); 3107 } 3108 }, this.dropTargetDelay + 10); 3109 } 3110 } 3111 else 3112 { 3113 timeOnTarget = new Date().getTime() - startTime; 3114 } 3115 3116 // Shift means disabled, delayed on cells with children, shows after this.dropTargetDelay, hides after 2500ms 3117 if (dropStyleEnabled && (timeOnTarget < 2500) && state != null && !mxEvent.isShiftDown(evt) && 3118 // If shape is equal or target has no stroke, fill and gradient then use longer delay except for images 3119 (((mxUtils.getValue(state.style, mxConstants.STYLE_SHAPE) != mxUtils.getValue(sourceCellStyle, mxConstants.STYLE_SHAPE) && 3120 (mxUtils.getValue(state.style, mxConstants.STYLE_STROKECOLOR, mxConstants.NONE) != mxConstants.NONE || 3121 mxUtils.getValue(state.style, mxConstants.STYLE_FILLCOLOR, mxConstants.NONE) != mxConstants.NONE || 3122 mxUtils.getValue(state.style, mxConstants.STYLE_GRADIENTCOLOR, mxConstants.NONE) != mxConstants.NONE)) || 3123 mxUtils.getValue(sourceCellStyle, mxConstants.STYLE_SHAPE) == 'image') || 3124 timeOnTarget > 1500 || graph.model.isEdge(state.cell)) && (timeOnTarget > this.dropTargetDelay) && 3125 !this.isDropStyleTargetIgnored(state) && ((graph.model.isVertex(state.cell) && firstVertex != null) || 3126 (graph.model.isEdge(state.cell) && graph.model.isEdge(cells[0])))) 3127 { 3128 if (graph.isCellEditable(state.cell)) 3129 { 3130 currentStyleTarget = state; 3131 var tmp = (graph.model.isEdge(state.cell)) ? graph.view.getPoint(state) : 3132 new mxPoint(state.getCenterX(), state.getCenterY()); 3133 tmp = new mxRectangle(tmp.x - this.refreshTarget.width / 2, tmp.y - this.refreshTarget.height / 2, 3134 this.refreshTarget.width, this.refreshTarget.height); 3135 3136 styleTarget.style.left = Math.floor(tmp.x) + 'px'; 3137 styleTarget.style.top = Math.floor(tmp.y) + 'px'; 3138 3139 if (styleTargetParent == null) 3140 { 3141 graph.container.appendChild(styleTarget); 3142 styleTargetParent = styleTarget.parentNode; 3143 } 3144 3145 checkArrow(x, y, tmp, styleTarget); 3146 } 3147 } 3148 // Does not reset on ignored edges 3149 else if (currentStyleTarget == null || !mxUtils.contains(currentStyleTarget, x, y) || 3150 (timeOnTarget > 1500 && !mxEvent.isShiftDown(evt))) 3151 { 3152 currentStyleTarget = null; 3153 3154 if (styleTargetParent != null) 3155 { 3156 styleTarget.parentNode.removeChild(styleTarget); 3157 styleTargetParent = null; 3158 } 3159 } 3160 else if (currentStyleTarget != null && styleTargetParent != null) 3161 { 3162 // Sets active Arrow as side effect 3163 var tmp = (graph.model.isEdge(currentStyleTarget.cell)) ? graph.view.getPoint(currentStyleTarget) : new mxPoint(currentStyleTarget.getCenterX(), currentStyleTarget.getCenterY()); 3164 tmp = new mxRectangle(tmp.x - this.refreshTarget.width / 2, tmp.y - this.refreshTarget.height / 2, 3165 this.refreshTarget.width, this.refreshTarget.height); 3166 checkArrow(x, y, tmp, styleTarget); 3167 } 3168 3169 // Checks if inside bounds 3170 if (activeTarget && currentTargetState != null && !mxEvent.isAltDown(evt) && activeArrow == null) 3171 { 3172 // LATER: Use hit-detection for edges 3173 bbox = mxRectangle.fromRectangle(currentTargetState); 3174 3175 if (graph.model.isEdge(currentTargetState.cell)) 3176 { 3177 var pts = currentTargetState.absolutePoints; 3178 3179 if (roundSource.parentNode != null) 3180 { 3181 var p0 = pts[0]; 3182 bbox.add(checkArrow(x, y, new mxRectangle(p0.x - this.roundDrop.width / 2, 3183 p0.y - this.roundDrop.height / 2, this.roundDrop.width, this.roundDrop.height), roundSource)); 3184 } 3185 3186 if (roundTarget.parentNode != null) 3187 { 3188 var pe = pts[pts.length - 1]; 3189 bbox.add(checkArrow(x, y, new mxRectangle(pe.x - this.roundDrop.width / 2, 3190 pe.y - this.roundDrop.height / 2, 3191 this.roundDrop.width, this.roundDrop.height), roundTarget)); 3192 } 3193 } 3194 else 3195 { 3196 var bds = mxRectangle.fromRectangle(currentTargetState); 3197 3198 // Uses outer bounding box to take rotation into account 3199 if (currentTargetState.shape != null && currentTargetState.shape.boundingBox != null) 3200 { 3201 bds = mxRectangle.fromRectangle(currentTargetState.shape.boundingBox); 3202 } 3203 3204 bds.grow(this.graph.tolerance); 3205 bds.grow(HoverIcons.prototype.arrowSpacing); 3206 3207 var handler = this.graph.selectionCellsHandler.getHandler(currentTargetState.cell); 3208 3209 if (handler != null) 3210 { 3211 bds.x -= handler.horizontalOffset / 2; 3212 bds.y -= handler.verticalOffset / 2; 3213 bds.width += handler.horizontalOffset; 3214 bds.height += handler.verticalOffset; 3215 3216 // Adds bounding box of rotation handle to avoid overlap 3217 if (handler.rotationShape != null && handler.rotationShape.node != null && 3218 handler.rotationShape.node.style.visibility != 'hidden' && 3219 handler.rotationShape.node.style.display != 'none' && 3220 handler.rotationShape.boundingBox != null) 3221 { 3222 bds.add(handler.rotationShape.boundingBox); 3223 } 3224 } 3225 3226 bbox.add(checkArrow(x, y, new mxRectangle(currentTargetState.getCenterX() - this.triangleUp.width / 2, 3227 bds.y - this.triangleUp.height, this.triangleUp.width, this.triangleUp.height), arrowUp)); 3228 bbox.add(checkArrow(x, y, new mxRectangle(bds.x + bds.width, 3229 currentTargetState.getCenterY() - this.triangleRight.height / 2, 3230 this.triangleRight.width, this.triangleRight.height), arrowRight)); 3231 bbox.add(checkArrow(x, y, new mxRectangle(currentTargetState.getCenterX() - this.triangleDown.width / 2, 3232 bds.y + bds.height, this.triangleDown.width, this.triangleDown.height), arrowDown)); 3233 bbox.add(checkArrow(x, y, new mxRectangle(bds.x - this.triangleLeft.width, 3234 currentTargetState.getCenterY() - this.triangleLeft.height / 2, 3235 this.triangleLeft.width, this.triangleLeft.height), arrowLeft)); 3236 } 3237 3238 // Adds tolerance 3239 if (bbox != null) 3240 { 3241 bbox.grow(10); 3242 } 3243 } 3244 3245 direction = mxConstants.DIRECTION_NORTH; 3246 3247 if (activeArrow == arrowRight) 3248 { 3249 direction = mxConstants.DIRECTION_EAST; 3250 } 3251 else if (activeArrow == arrowDown || activeArrow == roundTarget) 3252 { 3253 direction = mxConstants.DIRECTION_SOUTH; 3254 } 3255 else if (activeArrow == arrowLeft) 3256 { 3257 direction = mxConstants.DIRECTION_WEST; 3258 } 3259 3260 if (currentStyleTarget != null && activeArrow == styleTarget) 3261 { 3262 state = currentStyleTarget; 3263 } 3264 3265 var validTarget = (firstVertex == null || graph.isCellConnectable(cells[firstVertex])) && 3266 ((graph.model.isEdge(cell) && firstVertex != null) || 3267 (graph.model.isVertex(cell) && graph.isCellConnectable(cell))); 3268 3269 // Drop arrows shown after this.dropTargetDelay, hidden after 5 secs, switches arrows after 500ms 3270 if ((currentTargetState != null && timeOnTarget >= 5000) || 3271 (currentTargetState != state && 3272 (bbox == null || !mxUtils.contains(bbox, x, y) || 3273 (timeOnTarget > 500 && activeArrow == null && validTarget)))) 3274 { 3275 activeTarget = false; 3276 currentTargetState = ((timeOnTarget < 5000 && timeOnTarget > this.dropTargetDelay) || 3277 graph.model.isEdge(cell)) ? state : null; 3278 3279 if (currentTargetState != null && validTarget) 3280 { 3281 var elts = [roundSource, roundTarget, arrowUp, arrowRight, arrowDown, arrowLeft]; 3282 3283 for (var i = 0; i < elts.length; i++) 3284 { 3285 if (elts[i].parentNode != null) 3286 { 3287 elts[i].parentNode.removeChild(elts[i]); 3288 } 3289 } 3290 3291 if (graph.model.isEdge(cell)) 3292 { 3293 var pts = state.absolutePoints; 3294 3295 if (pts != null) 3296 { 3297 var p0 = pts[0]; 3298 var pe = pts[pts.length - 1]; 3299 var tol = graph.tolerance; 3300 var box = new mxRectangle(x - tol, y - tol, 2 * tol, 2 * tol); 3301 3302 roundSource.style.left = Math.floor(p0.x - this.roundDrop.width / 2) + 'px'; 3303 roundSource.style.top = Math.floor(p0.y - this.roundDrop.height / 2) + 'px'; 3304 3305 roundTarget.style.left = Math.floor(pe.x - this.roundDrop.width / 2) + 'px'; 3306 roundTarget.style.top = Math.floor(pe.y - this.roundDrop.height / 2) + 'px'; 3307 3308 if (graph.model.getTerminal(cell, true) == null) 3309 { 3310 graph.container.appendChild(roundSource); 3311 } 3312 3313 if (graph.model.getTerminal(cell, false) == null) 3314 { 3315 graph.container.appendChild(roundTarget); 3316 } 3317 } 3318 } 3319 else 3320 { 3321 var bds = mxRectangle.fromRectangle(state); 3322 3323 // Uses outer bounding box to take rotation into account 3324 if (state.shape != null && state.shape.boundingBox != null) 3325 { 3326 bds = mxRectangle.fromRectangle(state.shape.boundingBox); 3327 } 3328 3329 bds.grow(this.graph.tolerance); 3330 bds.grow(HoverIcons.prototype.arrowSpacing); 3331 3332 var handler = this.graph.selectionCellsHandler.getHandler(state.cell); 3333 3334 if (handler != null) 3335 { 3336 bds.x -= handler.horizontalOffset / 2; 3337 bds.y -= handler.verticalOffset / 2; 3338 bds.width += handler.horizontalOffset; 3339 bds.height += handler.verticalOffset; 3340 3341 // Adds bounding box of rotation handle to avoid overlap 3342 if (handler.rotationShape != null && handler.rotationShape.node != null && 3343 handler.rotationShape.node.style.visibility != 'hidden' && 3344 handler.rotationShape.node.style.display != 'none' && 3345 handler.rotationShape.boundingBox != null) 3346 { 3347 bds.add(handler.rotationShape.boundingBox); 3348 } 3349 } 3350 3351 arrowUp.style.left = Math.floor(state.getCenterX() - this.triangleUp.width / 2) + 'px'; 3352 arrowUp.style.top = Math.floor(bds.y - this.triangleUp.height) + 'px'; 3353 3354 arrowRight.style.left = Math.floor(bds.x + bds.width) + 'px'; 3355 arrowRight.style.top = Math.floor(state.getCenterY() - this.triangleRight.height / 2) + 'px'; 3356 3357 arrowDown.style.left = arrowUp.style.left 3358 arrowDown.style.top = Math.floor(bds.y + bds.height) + 'px'; 3359 3360 arrowLeft.style.left = Math.floor(bds.x - this.triangleLeft.width) + 'px'; 3361 arrowLeft.style.top = arrowRight.style.top; 3362 3363 if (state.style['portConstraint'] != 'eastwest') 3364 { 3365 graph.container.appendChild(arrowUp); 3366 graph.container.appendChild(arrowDown); 3367 } 3368 3369 graph.container.appendChild(arrowRight); 3370 graph.container.appendChild(arrowLeft); 3371 } 3372 3373 // Hides handle for cell under mouse 3374 if (state != null) 3375 { 3376 currentStateHandle = graph.selectionCellsHandler.getHandler(state.cell); 3377 3378 if (currentStateHandle != null && currentStateHandle.setHandlesVisible != null) 3379 { 3380 currentStateHandle.setHandlesVisible(false); 3381 } 3382 } 3383 3384 activeTarget = true; 3385 } 3386 else 3387 { 3388 var elts = [roundSource, roundTarget, arrowUp, arrowRight, arrowDown, arrowLeft]; 3389 3390 for (var i = 0; i < elts.length; i++) 3391 { 3392 if (elts[i].parentNode != null) 3393 { 3394 elts[i].parentNode.removeChild(elts[i]); 3395 } 3396 } 3397 } 3398 } 3399 3400 if (!activeTarget && currentStateHandle != null) 3401 { 3402 currentStateHandle.setHandlesVisible(true); 3403 } 3404 3405 // Handles drop target 3406 var target = ((!mxEvent.isAltDown(evt) || mxEvent.isShiftDown(evt)) && 3407 !(currentStyleTarget != null && activeArrow == styleTarget)) ? 3408 mxDragSource.prototype.getDropTarget.apply(this, arguments) : null; 3409 var model = graph.getModel(); 3410 3411 if (target != null) 3412 { 3413 if (activeArrow != null || !graph.isSplitTarget(target, cells, evt)) 3414 { 3415 // Selects parent group as drop target 3416 while (target != null && !graph.isValidDropTarget(target, cells, evt) && 3417 model.isVertex(model.getParent(target))) 3418 { 3419 target = model.getParent(target); 3420 } 3421 3422 if (target != null && (graph.view.currentRoot == target || 3423 (!graph.isValidRoot(target) && 3424 graph.getModel().getChildCount(target) == 0) || 3425 graph.isCellLocked(target) || model.isEdge(target) || 3426 !graph.isValidDropTarget(target, cells, evt))) 3427 { 3428 target = null; 3429 } 3430 } 3431 } 3432 3433 if (graph.isCellLocked(target)) 3434 { 3435 target = null; 3436 } 3437 3438 return target; 3439 }); 3440 3441 dragSource.stopDrag = function() 3442 { 3443 mxDragSource.prototype.stopDrag.apply(this, arguments); 3444 3445 var elts = [roundSource, roundTarget, styleTarget, arrowUp, arrowRight, arrowDown, arrowLeft]; 3446 3447 for (var i = 0; i < elts.length; i++) 3448 { 3449 if (elts[i].parentNode != null) 3450 { 3451 elts[i].parentNode.removeChild(elts[i]); 3452 } 3453 } 3454 3455 if (currentTargetState != null && currentStateHandle != null) 3456 { 3457 currentStateHandle.reset(); 3458 } 3459 3460 currentStateHandle = null; 3461 currentTargetState = null; 3462 currentStyleTarget = null; 3463 styleTargetParent = null; 3464 activeArrow = null; 3465 }; 3466 3467 return dragSource; 3468}; 3469 3470/** 3471 * Adds a handler for inserting the cell with a single click. 3472 */ 3473Sidebar.prototype.itemClicked = function(cells, ds, evt, elt) 3474{ 3475 var graph = this.editorUi.editor.graph; 3476 graph.container.focus(); 3477 3478 // Alt+Click inserts and connects 3479 if (mxEvent.isAltDown(evt) && graph.getSelectionCount() == 1 && 3480 graph.model.isVertex(graph.getSelectionCell())) 3481 { 3482 var firstVertex = null; 3483 3484 for (var i = 0; i < cells.length && firstVertex == null; i++) 3485 { 3486 if (graph.model.isVertex(cells[i])) 3487 { 3488 firstVertex = i; 3489 } 3490 } 3491 3492 if (firstVertex != null) 3493 { 3494 graph.setSelectionCells(this.dropAndConnect(graph.getSelectionCell(), cells, 3495 (mxEvent.isMetaDown(evt) || mxEvent.isControlDown(evt)) ? 3496 (mxEvent.isShiftDown(evt) ? mxConstants.DIRECTION_WEST : mxConstants.DIRECTION_NORTH) : 3497 (mxEvent.isShiftDown(evt) ? mxConstants.DIRECTION_EAST : mxConstants.DIRECTION_SOUTH), 3498 firstVertex, evt)); 3499 graph.scrollCellToVisible(graph.getSelectionCell()); 3500 } 3501 } 3502 // Shift+Click updates shape 3503 else if (mxEvent.isShiftDown(evt) && !graph.isSelectionEmpty()) 3504 { 3505 var temp = graph.getEditableCells(graph.getSelectionCells()); 3506 this.updateShapes(cells[0], temp); 3507 graph.scrollCellToVisible(temp); 3508 } 3509 else 3510 { 3511 var pt = (mxEvent.isAltDown(evt)) ? graph.getFreeInsertPoint() : 3512 graph.getCenterInsertPoint(graph.getBoundingBoxFromGeometry(cells, true)); 3513 ds.drop(graph, evt, null, pt.x, pt.y, true); 3514 } 3515}; 3516 3517/** 3518 * Adds a handler for inserting the cell with a single click. 3519 */ 3520Sidebar.prototype.addClickHandler = function(elt, ds, cells) 3521{ 3522 var graph = this.editorUi.editor.graph; 3523 var oldMouseDown = ds.mouseDown; 3524 var oldMouseMove = ds.mouseMove; 3525 var oldMouseUp = ds.mouseUp; 3526 var tol = graph.tolerance; 3527 var first = null; 3528 var sb = this; 3529 3530 ds.mouseDown =function(evt) 3531 { 3532 oldMouseDown.apply(this, arguments); 3533 first = new mxPoint(mxEvent.getClientX(evt), mxEvent.getClientY(evt)); 3534 3535 if (this.dragElement != null) 3536 { 3537 this.dragElement.style.display = 'none'; 3538 mxUtils.setOpacity(elt, 50); 3539 } 3540 }; 3541 3542 ds.mouseMove = function(evt) 3543 { 3544 if (this.dragElement != null && this.dragElement.style.display == 'none' && 3545 first != null && (Math.abs(first.x - mxEvent.getClientX(evt)) > tol || 3546 Math.abs(first.y - mxEvent.getClientY(evt)) > tol)) 3547 { 3548 this.dragElement.style.display = ''; 3549 mxUtils.setOpacity(elt, 100); 3550 } 3551 3552 oldMouseMove.apply(this, arguments); 3553 }; 3554 3555 ds.mouseUp = function(evt) 3556 { 3557 try 3558 { 3559 if (!mxEvent.isPopupTrigger(evt) && this.currentGraph == null && 3560 this.dragElement != null && this.dragElement.style.display == 'none') 3561 { 3562 sb.itemClicked(cells, ds, evt, elt); 3563 } 3564 3565 oldMouseUp.apply(ds, arguments); 3566 mxUtils.setOpacity(elt, 100); 3567 first = null; 3568 3569 // Blocks tooltips on this element after single click 3570 sb.currentElt = elt; 3571 } 3572 catch (e) 3573 { 3574 ds.reset(); 3575 sb.editorUi.handleError(e); 3576 } 3577 }; 3578}; 3579 3580/** 3581 * Creates a drop handler for inserting the given cells. 3582 */ 3583Sidebar.prototype.createVertexTemplateEntry = function(style, width, height, value, title, showLabel, showTitle, tags) 3584{ 3585 if (tags != null && title != null) 3586 { 3587 tags += ' ' + title; 3588 } 3589 3590 tags = (tags != null && tags.length > 0) ? tags : ((title != null) ? title.toLowerCase() : ''); 3591 3592 return this.addEntry(tags, mxUtils.bind(this, function() 3593 { 3594 return this.createVertexTemplate(style, width, height, value, title, showLabel, showTitle); 3595 })); 3596} 3597 3598/** 3599 * Creates a drop handler for inserting the given cells. 3600 */ 3601Sidebar.prototype.createVertexTemplate = function(style, width, height, value, title, showLabel, showTitle, allowCellsInserted, showTooltip) 3602{ 3603 var cells = [new mxCell((value != null) ? value : '', new mxGeometry(0, 0, width, height), style)]; 3604 cells[0].vertex = true; 3605 3606 return this.createVertexTemplateFromCells(cells, width, height, title, showLabel, showTitle, allowCellsInserted, showTooltip); 3607}; 3608 3609/** 3610 * Creates a drop handler for inserting the given cells. 3611 */ 3612Sidebar.prototype.createVertexTemplateFromData = function(data, width, height, title, showLabel, showTitle, allowCellsInserted, showTooltip) 3613{ 3614 var doc = mxUtils.parseXml(Graph.decompress(data)); 3615 var codec = new mxCodec(doc); 3616 3617 var model = new mxGraphModel(); 3618 codec.decode(doc.documentElement, model); 3619 3620 var cells = this.graph.cloneCells(model.root.getChildAt(0).children); 3621 3622 return this.createVertexTemplateFromCells(cells, width, height, title, showLabel, showTitle, allowCellsInserted, showTooltip); 3623}; 3624 3625/** 3626 * Creates a drop handler for inserting the given cells. 3627 */ 3628Sidebar.prototype.createVertexTemplateFromCells = function(cells, width, height, title, showLabel, showTitle, allowCellsInserted, showTooltip) 3629{ 3630 // Use this line to convert calls to this function with lots of boilerplate code for creating cells 3631 //console.trace('xml', Graph.compress(mxUtils.getXml(this.graph.encodeCells(cells))), cells); 3632 return this.createItem(cells, title, showLabel, showTitle, width, height, allowCellsInserted, showTooltip); 3633}; 3634 3635/** 3636 * 3637 */ 3638Sidebar.prototype.createEdgeTemplateEntry = function(style, width, height, value, title, showLabel, tags, allowCellsInserted, showTooltip) 3639{ 3640 tags = (tags != null && tags.length > 0) ? tags : title.toLowerCase(); 3641 3642 return this.addEntry(tags, mxUtils.bind(this, function() 3643 { 3644 return this.createEdgeTemplate(style, width, height, value, title, showLabel, allowCellsInserted, showTooltip); 3645 })); 3646}; 3647 3648/** 3649 * Creates a drop handler for inserting the given cells. 3650 */ 3651Sidebar.prototype.createEdgeTemplate = function(style, width, height, value, title, showLabel, allowCellsInserted, showTooltip) 3652{ 3653 var cell = new mxCell((value != null) ? value : '', new mxGeometry(0, 0, width, height), style); 3654 cell.geometry.setTerminalPoint(new mxPoint(0, height), true); 3655 cell.geometry.setTerminalPoint(new mxPoint(width, 0), false); 3656 cell.geometry.relative = true; 3657 cell.edge = true; 3658 3659 return this.createEdgeTemplateFromCells([cell], width, height, title, showLabel, allowCellsInserted, showTooltip); 3660}; 3661 3662/** 3663 * Creates a drop handler for inserting the given cells. 3664 */ 3665Sidebar.prototype.createEdgeTemplateFromCells = function(cells, width, height, title, showLabel, allowCellsInserted, showTooltip, showTitle) 3666{ 3667 return this.createItem(cells, title, showLabel, (showTitle != null) ? showTitle : true, width, height, allowCellsInserted, showTooltip); 3668}; 3669 3670/** 3671 * Adds the given palette. 3672 */ 3673Sidebar.prototype.addPaletteFunctions = function(id, title, expanded, fns) 3674{ 3675 this.addPalette(id, title, expanded, mxUtils.bind(this, function(content) 3676 { 3677 for (var i = 0; i < fns.length; i++) 3678 { 3679 content.appendChild(fns[i](content)); 3680 } 3681 })); 3682}; 3683 3684/** 3685 * Adds the given palette. 3686 */ 3687Sidebar.prototype.addPalette = function(id, title, expanded, onInit) 3688{ 3689 var elt = this.createTitle(title); 3690 this.container.appendChild(elt); 3691 3692 var div = document.createElement('div'); 3693 div.className = 'geSidebar'; 3694 3695 // Disables built-in pan and zoom in IE10 and later 3696 if (mxClient.IS_POINTER) 3697 { 3698 div.style.touchAction = 'none'; 3699 } 3700 3701 if (expanded) 3702 { 3703 onInit(div); 3704 onInit = null; 3705 } 3706 else 3707 { 3708 div.style.display = 'none'; 3709 } 3710 3711 this.addFoldingHandler(elt, div, onInit); 3712 3713 var outer = document.createElement('div'); 3714 outer.appendChild(div); 3715 this.container.appendChild(outer); 3716 3717 // Keeps references to the DOM nodes 3718 if (id != null) 3719 { 3720 this.palettes[id] = [elt, outer]; 3721 } 3722 3723 return div; 3724}; 3725 3726/** 3727 * Create the given title element. 3728 */ 3729Sidebar.prototype.addFoldingHandler = function(title, content, funct) 3730{ 3731 var initialized = false; 3732 3733 // Avoids mixed content warning in IE6-8 3734 if (!mxClient.IS_IE || document.documentMode >= 8) 3735 { 3736 title.style.backgroundImage = (content.style.display == 'none') ? 3737 'url(\'' + this.collapsedImage + '\')' : 'url(\'' + this.expandedImage + '\')'; 3738 } 3739 3740 title.style.backgroundRepeat = 'no-repeat'; 3741 title.style.backgroundPosition = '0% 50%'; 3742 3743 mxEvent.addListener(title, 'click', mxUtils.bind(this, function(evt) 3744 { 3745 if (content.style.display == 'none') 3746 { 3747 if (!initialized) 3748 { 3749 initialized = true; 3750 3751 if (funct != null) 3752 { 3753 // Wait cursor does not show up on Mac 3754 title.style.cursor = 'wait'; 3755 var prev = title.innerHTML; 3756 title.innerHTML = mxResources.get('loading') + '...'; 3757 3758 window.setTimeout(function() 3759 { 3760 content.style.display = 'block'; 3761 title.style.cursor = ''; 3762 title.innerHTML = prev; 3763 3764 var fo = mxClient.NO_FO; 3765 mxClient.NO_FO = Editor.prototype.originalNoForeignObject; 3766 funct(content, title); 3767 mxClient.NO_FO = fo; 3768 }, (mxClient.IS_FF) ? 20 : 0); 3769 } 3770 else 3771 { 3772 content.style.display = 'block'; 3773 } 3774 } 3775 else 3776 { 3777 content.style.display = 'block'; 3778 } 3779 3780 title.style.backgroundImage = 'url(\'' + this.expandedImage + '\')'; 3781 } 3782 else 3783 { 3784 title.style.backgroundImage = 'url(\'' + this.collapsedImage + '\')'; 3785 content.style.display = 'none'; 3786 } 3787 3788 mxEvent.consume(evt); 3789 })); 3790 3791 // Prevents focus 3792 mxEvent.addListener(title, (mxClient.IS_POINTER) ? 'pointerdown' : 'mousedown', 3793 mxUtils.bind(this, function(evt) 3794 { 3795 evt.preventDefault(); 3796 })); 3797}; 3798 3799/** 3800 * Removes the palette for the given ID. 3801 */ 3802Sidebar.prototype.removePalette = function(id) 3803{ 3804 var elts = this.palettes[id]; 3805 3806 if (elts != null) 3807 { 3808 this.palettes[id] = null; 3809 3810 for (var i = 0; i < elts.length; i++) 3811 { 3812 this.container.removeChild(elts[i]); 3813 } 3814 3815 return true; 3816 } 3817 3818 return false; 3819}; 3820 3821/** 3822 * Adds the given image palette. 3823 */ 3824Sidebar.prototype.addImagePalette = function(id, title, prefix, postfix, items, titles, tags) 3825{ 3826 var showTitles = titles != null; 3827 var fns = []; 3828 3829 for (var i = 0; i < items.length; i++) 3830 { 3831 (mxUtils.bind(this, function(item, title, tmpTags) 3832 { 3833 if (tmpTags == null) 3834 { 3835 var slash = item.lastIndexOf('/'); 3836 var dot = item.lastIndexOf('.'); 3837 tmpTags = item.substring((slash >= 0) ? slash + 1 : 0, (dot >= 0) ? dot : item.length).replace(/[-_]/g, ' '); 3838 } 3839 3840 fns.push(this.createVertexTemplateEntry('image;html=1;image=' + prefix + item + postfix, 3841 this.defaultImageWidth, this.defaultImageHeight, '', title, title != null, null, this.filterTags(tmpTags))); 3842 }))(items[i], (titles != null) ? titles[i] : null, (tags != null) ? tags[items[i]] : null); 3843 } 3844 3845 this.addPaletteFunctions(id, title, false, fns); 3846}; 3847 3848/** 3849 * Creates the array of tags for the given stencil. Duplicates are allowed and will be filtered out later. 3850 */ 3851Sidebar.prototype.getTagsForStencil = function(packageName, stencilName, moreTags) 3852{ 3853 var tags = packageName.split('.'); 3854 3855 for (var i = 1; i < tags.length; i++) 3856 { 3857 tags[i] = tags[i].replace(/_/g, ' ') 3858 } 3859 3860 tags.push(stencilName.replace(/_/g, ' ')); 3861 3862 if (moreTags != null) 3863 { 3864 tags.push(moreTags); 3865 } 3866 3867 return tags.slice(1, tags.length); 3868}; 3869 3870/** 3871 * Adds the given stencil palette. 3872 */ 3873Sidebar.prototype.addStencilPalette = function(id, title, stencilFile, style, ignore, onInit, scale, tags, customFns, groupId) 3874{ 3875 scale = (scale != null) ? scale : 1; 3876 3877 if (this.addStencilsToIndex) 3878 { 3879 // LATER: Handle asynchronous loading dependency 3880 var fns = []; 3881 3882 if (customFns != null) 3883 { 3884 for (var i = 0; i < customFns.length; i++) 3885 { 3886 fns.push(customFns[i]); 3887 } 3888 } 3889 3890 mxStencilRegistry.loadStencilSet(stencilFile, mxUtils.bind(this, function(packageName, stencilName, displayName, w, h) 3891 { 3892 if (ignore == null || mxUtils.indexOf(ignore, stencilName) < 0) 3893 { 3894 var tmp = this.getTagsForStencil(packageName, stencilName); 3895 var tmpTags = (tags != null) ? tags[stencilName] : null; 3896 3897 if (tmpTags != null) 3898 { 3899 tmp.push(tmpTags); 3900 } 3901 3902 fns.push(this.createVertexTemplateEntry('shape=' + packageName + stencilName.toLowerCase() + style, 3903 Math.round(w * scale), Math.round(h * scale), '', stencilName.replace(/_/g, ' '), null, null, 3904 this.filterTags(tmp.join(' ')))); 3905 } 3906 }), true, true); 3907 3908 this.addPaletteFunctions(id, title, false, fns); 3909 } 3910 else 3911 { 3912 this.addPalette(id, title, false, mxUtils.bind(this, function(content) 3913 { 3914 if (style == null) 3915 { 3916 style = ''; 3917 } 3918 3919 if (onInit != null) 3920 { 3921 onInit.call(this, content); 3922 } 3923 3924 if (customFns != null) 3925 { 3926 for (var i = 0; i < customFns.length; i++) 3927 { 3928 customFns[i](content); 3929 } 3930 } 3931 3932 mxStencilRegistry.loadStencilSet(stencilFile, mxUtils.bind(this, function(packageName, stencilName, displayName, w, h) 3933 { 3934 if (ignore == null || mxUtils.indexOf(ignore, stencilName) < 0) 3935 { 3936 content.appendChild(this.createVertexTemplate('shape=' + packageName + stencilName.toLowerCase() + style, 3937 Math.round(w * scale), Math.round(h * scale), '', stencilName.replace(/_/g, ' '), true)); 3938 } 3939 }), true); 3940 })); 3941 } 3942}; 3943 3944/** 3945 * Adds the given stencil palette. 3946 */ 3947Sidebar.prototype.destroy = function() 3948{ 3949 if (this.graph != null) 3950 { 3951 if (this.graph.container != null && this.graph.container.parentNode != null) 3952 { 3953 this.graph.container.parentNode.removeChild(this.graph.container); 3954 } 3955 3956 this.graph.destroy(); 3957 this.graph = null; 3958 } 3959 3960 if (this.pointerUpHandler != null) 3961 { 3962 mxEvent.removeListener(document, (mxClient.IS_POINTER) ? 'pointerup' : 'mouseup', this.pointerUpHandler); 3963 this.pointerUpHandler = null; 3964 } 3965 3966 if (this.pointerDownHandler != null) 3967 { 3968 mxEvent.removeListener(document, (mxClient.IS_POINTER) ? 'pointerdown' : 'mousedown', this.pointerDownHandler); 3969 this.pointerDownHandler = null; 3970 } 3971 3972 if (this.pointerMoveHandler != null) 3973 { 3974 mxEvent.removeListener(document, (mxClient.IS_POINTER) ? 'pointermove' : 'mousemove', this.pointerMoveHandler); 3975 this.pointerMoveHandler = null; 3976 } 3977 3978 if (this.pointerOutHandler != null) 3979 { 3980 mxEvent.removeListener(document, (mxClient.IS_POINTER) ? 'pointerout' : 'mouseout', this.pointerOutHandler); 3981 this.pointerOutHandler = null; 3982 } 3983}; 3984