Sidebar.js 163 KB

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