all-planner.js 64 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074
  1. Ext.ns('App');
  2. App = {
  3. webforms: {},
  4. init: function() {
  5. Ext.QuickTips.init();
  6. this.propertyManager = new App.property.PropertyManager();
  7. var viewport = new Ext.Viewport({
  8. layout: 'border',
  9. items: [
  10. this.createNorth(),
  11. this.createSouth(),
  12. this.createWest(),
  13. this.createEast(),
  14. this.createCenter()
  15. ]
  16. });
  17. this.initEditor();
  18. setTimeout(function() {
  19. Ext.get('loading').remove();
  20. Ext.get('loading-mask').fadeOut({remove:true});
  21. }, 100);
  22. },
  23. initEditor: function() {
  24. var xml = "<?xml version='1.0' encoding='UTF-8'?>"
  25. + "<process name='untitled' xmlns='http://jbpm.org/4.4/jpdl'>"
  26. + "<image g='100,100,716,1200' url='images/stenciles/planner/2d/layout.png' />"
  27. + "<image g='146,614,51,29' url='images/stenciles/planner/2d/hand.png' />"
  28. + "<image g='268,316,118,147' url='images/stenciles/planner/2d/table.png' />"
  29. + "<image g='636,134,145,197' url='images/stenciles/planner/2d/desk.png' />"
  30. + "<image g='602,482,123,51' url='images/stenciles/planner/2d/coach1.png' />"
  31. + "<image g='132,680,78,42' url='images/stenciles/planner/2d/toilet.png' />"
  32. + "<image g='360,600,52,170' url='images/stenciles/planner/2d/tv.png' />"
  33. + "<image g='134,740,190,58' url='images/stenciles/planner/2d/bath.png' />"
  34. + "<image g='130,932,243,163' url='images/stenciles/planner/2d/bed1.png' />"
  35. + "<image g='556,930,228,146' url='images/stenciles/planner/2d/bed2.png' />"
  36. + "<image g='720,880,46,37' url='images/stenciles/planner/2d/chair.png' />"
  37. + "<image g='138,892,46,37' url='images/stenciles/planner/2d/chair.png' />"
  38. + "<image g='140,1100,46,37' url='images/stenciles/planner/2d/chair.png' />"
  39. + "<image g='710,1100,46,37' url='images/stenciles/planner/2d/chair.png' />"
  40. + "<image g='728,666,57,132' url='images/stenciles/planner/2d/coach2.png' />"
  41. + "<image g='728,538,57,132' url='images/stenciles/planner/2d/coach2.png' />"
  42. + "<image g='727,485,56,45' url='images/stenciles/planner/2d/flowers2.png' />"
  43. + "<rect g='593,835,190,38' rounded=\"1\" fill=\"#FFCC00\" />"
  44. + "<rect g='137,835,190,38' rounded=\"1\" fill=\"#FFCC00\" />"
  45. + "<rect g='605,545,105,245' fill=\"#FFCC99\" />"
  46. + "<rect g='632,602,54,142' rounded=\"1\" />"
  47. + "<image g='395,133,81,41' url='images/stenciles/planner/2d/disc.png' />"
  48. + "<image g='659,359,95,60' url='images/stenciles/planner/2d/flowers.png' />"
  49. + "<image g='299,135,86,35' url='images/stenciles/planner/2d/water.png' />"
  50. + "</process>";
  51. var editor = new Gef.jbs.ExtEditor();
  52. var input = new Gef.jbs.JBSEditorInput();
  53. input.readXml(xml);
  54. var workbenchWindow = new Gef.ui.support.DefaultWorkbenchWindow();
  55. workbenchWindow.getActivePage().openEditor(editor, input);
  56. workbenchWindow.render();
  57. Gef.activeEditor = editor;
  58. this.propertyManager.initSelectionListener(editor);
  59. },
  60. getProcessModel: function() {
  61. var viewer = Gef.activeEditor.getGraphicalViewer();
  62. var processEditPart = viewer.getContents();
  63. return processEditPart.model;
  64. },
  65. createNorth: function() {
  66. var p = null;
  67. if (Gef.MODE_DEMO === true) {
  68. p = new Ext.Panel({
  69. region: 'north'
  70. });
  71. } else {
  72. p = new Ext.Panel({
  73. region: 'north',
  74. html: '<h1 id="pageh1">Web户型图设计器 - 多比图形控件演示<h1>'
  75. });
  76. }
  77. App.northPanel = p;
  78. return p;
  79. },
  80. createSouth: function() {
  81. var p = this.propertyManager.getBottom();
  82. return p;
  83. },
  84. createWest: function() {
  85. var p = new App.PalettePanel({
  86. collapsible: true
  87. });
  88. App.westPanel = p;
  89. return p;
  90. },
  91. createEast: function() {
  92. var p = this.propertyManager.getRight();
  93. return p;
  94. },
  95. createCenter: function() {
  96. var p = new App.CanvasPanel();
  97. App.centerPanel = p;
  98. return p;
  99. },
  100. getSelectionListener: function() {
  101. if (!this.selectionListener) {
  102. this.selectionListener = new Gef.jbs.ExtSelectionListener(null);
  103. }
  104. return this.selectionListener;
  105. }
  106. };
  107. /*
  108. Gef.override(App.PalettePanel, {
  109. configItems: function() {
  110. this.html = 'sdfasfdfdsa';
  111. }
  112. });
  113. */
  114. //Gef.PALETTE_TYPE = 'plain';
  115. Gef.PALETTE_TYPE = 'accordion';
  116. Ext.onReady(App.init, App);
  117. App.CanvasPanel = Ext.extend(Ext.Panel, {
  118. initComponent: function() {
  119. //this.on('bodyresize', function(p, w, h) {
  120. // var b = p.body.getBox();
  121. //});
  122. this.region = 'center';
  123. this.autoScroll = true;
  124. this.tbar = new Ext.Toolbar([{
  125. text: '新建',
  126. iconCls: 'tb-new',
  127. handler: function() {
  128. Gef.activeEditor.reset();
  129. }
  130. }, {
  131. text: '导入',
  132. iconCls: 'tb-webform',
  133. handler: function() {
  134. var xml = Gef.activeEditor.serial();
  135. if (!this.openWin) {
  136. this.openWin = new Ext.Window({
  137. title: 'xml',
  138. layout: 'fit',
  139. width: 500,
  140. height: 300,
  141. closeAction: 'hide',
  142. modal: true,
  143. items: [{
  144. id: '__gef_jbpm4_xml_import__',
  145. xtype: 'textarea'
  146. }],
  147. buttons: [{
  148. text: '导入',
  149. handler: function() {
  150. var xml = Ext.getDom('__gef_jbpm4_xml_import__').value;
  151. Gef.activeEditor.resetAndOpen(xml);
  152. this.openWin.hide();
  153. },
  154. scope: this
  155. }, {
  156. text: '取消',
  157. handler: function() {
  158. this.openWin.hide();
  159. },
  160. scope: this
  161. }]
  162. });
  163. this.openWin.on('show', function() {
  164. Gef.activeEditor.disable();
  165. });
  166. this.openWin.on('hide', function() {
  167. Gef.activeEditor.enable();
  168. });
  169. }
  170. this.openWin.show(null, function() {
  171. Ext.getDom('__gef_jbpm4_xml_import__').value = xml;
  172. });
  173. }
  174. }, {
  175. text: '导出',
  176. iconCls: 'tb-prop',
  177. handler: function() {
  178. var xml = Gef.activeEditor.serial();
  179. if (!this.openWin) {
  180. this.openWin = new Ext.Window({
  181. title: 'xml',
  182. layout: 'fit',
  183. width: 500,
  184. height: 300,
  185. closeAction: 'hide',
  186. modal: true,
  187. items: [{
  188. id: '__gef_jbpm4_xml_export__',
  189. xtype: 'textarea'
  190. }],
  191. buttons: [{
  192. text: '关闭',
  193. handler: function() {
  194. this.openWin.hide();
  195. },
  196. scope: this
  197. }]
  198. });
  199. this.openWin.on('show', function() {
  200. Gef.activeEditor.disable();
  201. });
  202. this.openWin.on('hide', function() {
  203. Gef.activeEditor.enable();
  204. });
  205. }
  206. this.openWin.show(null, function() {
  207. Ext.getDom('__gef_jbpm4_xml_export__').value = xml;
  208. });
  209. }
  210. }, {
  211. text: '保存',
  212. iconCls: 'tb-save',
  213. handler: function() {
  214. var editor = Gef.activeEditor;
  215. var xml = editor.serial();
  216. var name = editor.getGraphicalViewer().getContents().getModel().text;
  217. Ext.Msg.wait('正在保存');
  218. Ext.Ajax.request({
  219. method: 'post',
  220. url: Gef.SAVE_URL,
  221. success: function(response) {
  222. try {
  223. var o = Ext.decode(response.responseText);
  224. if (o.success === true) {
  225. Ext.Msg.alert('信息', '操作成功');
  226. } else {
  227. Ext.Msg.alert('错误', o.errors.msg);
  228. }
  229. } catch(e) {
  230. Ext.Msg.alert('系统错误', response.responseText);
  231. }
  232. },
  233. failure: function(response) {
  234. Ext.Msg.alert('系统错误', response.responseText);
  235. },
  236. params: {
  237. id: Gef.PROCESS_ID,
  238. processName: name,
  239. xml: xml
  240. }
  241. });
  242. }
  243. }, {
  244. text: '发布',
  245. iconCls: 'tb-deploy',
  246. handler: function() {
  247. var editor = Gef.activeEditor;
  248. var isValid = new Validation(editor).validate();
  249. if (!isValid) {
  250. return false;
  251. }
  252. var xml = editor.serial();
  253. var model = editor.getGraphicalViewer().getContents().getModel();
  254. var name = model.text;
  255. Ext.Msg.wait('正在发布');
  256. Ext.Ajax.request({
  257. method: 'post',
  258. url: Gef.DEPLOY_URL,
  259. success: function(response) {
  260. try {
  261. var o = Ext.decode(response.responseText);
  262. if (o.success === true) {
  263. Ext.Msg.alert('信息', '操作成功');
  264. } else {
  265. Ext.Msg.alert('错误', o.errors.msg);
  266. }
  267. } catch(e) {
  268. Ext.Msg.alert('系统错误', response.responseText);
  269. }
  270. },
  271. failure: function(response) {
  272. Ext.Msg.alert('系统错误', response.responseText);
  273. },
  274. params: {
  275. id: Gef.PROCESS_ID,
  276. procCatId: model.procCatId,
  277. procDefName: model.procDefName,
  278. procDefCode: model.procDefCode,
  279. procVerName: model.procVerName,
  280. xml: xml
  281. }
  282. });
  283. }
  284. }, {
  285. text: '清空',
  286. iconCls: 'tb-clear',
  287. handler: function() {
  288. Gef.activeEditor.clear();
  289. }
  290. }, {
  291. text: '撤销',
  292. iconCls: 'tb-undo',
  293. handler: function() {
  294. var viewer = Gef.activeEditor.getGraphicalViewer();
  295. var browserListener = viewer.getBrowserListener();
  296. var selectionManager = browserListener.getSelectionManager();
  297. selectionManager.clearAll();
  298. var commandStack = viewer.getEditDomain().getCommandStack();
  299. commandStack.undo();
  300. },
  301. scope: this
  302. }, {
  303. text: '重做',
  304. iconCls: 'tb-redo',
  305. handler: function() {
  306. var viewer = Gef.activeEditor.getGraphicalViewer();
  307. var browserListener = viewer.getBrowserListener();
  308. var selectionManager = browserListener.getSelectionManager();
  309. selectionManager.clearAll();
  310. var commandStack = viewer.getEditDomain().getCommandStack();
  311. commandStack.redo();
  312. },
  313. scope: this
  314. }, {
  315. text: '布局',
  316. iconCls: 'tb-activity',
  317. handler: function() {
  318. var viewer = Gef.activeEditor.getGraphicalViewer();
  319. var browserListener = viewer.getBrowserListener();
  320. var selectionManager = browserListener.getSelectionManager();
  321. selectionManager.clearAll();
  322. new Layout(Gef.activeEditor).doLayout();
  323. },
  324. scope: this
  325. }, {
  326. text: '删除',
  327. iconCls: 'tb-delete',
  328. handler: this.removeSelected,
  329. scope: this
  330. }]);
  331. App.CanvasPanel.superclass.initComponent.call(this);
  332. },
  333. afterRender: function() {
  334. App.CanvasPanel.superclass.afterRender.call(this);
  335. var width = 3000;
  336. var height = 2500;
  337. Ext.DomHelper.append(this.body, [{
  338. id: '__gef_jbs__',
  339. tag: 'div',
  340. style: 'width:' + (width + 10) + 'px;height:' + (height + 10) + 'px;',
  341. children: [{
  342. id: '__gef_jbs_center__',
  343. tag: 'div',
  344. style: 'width:' + width + 'px;height:' + height + 'px;float:left;'
  345. }, {
  346. id: '__gef_jbs_right__',
  347. tag: 'div',
  348. style: 'width:10px;height:' + height + 'px;float:left;background-color:#EEEEEE;cursor:pointer;'
  349. }, {
  350. id: '__gef_jbs_bottom__',
  351. tag: 'div',
  352. style: 'width:' + (width + 10) + 'px;height:10px;float:left;background-color:#EEEEEE;cursor:pointer;'
  353. }]
  354. }]);
  355. var rightEl = Ext.fly('__gef_jbs_right__');
  356. rightEl.on('mouseover', function(e) {
  357. var t = e.getTarget();
  358. t.style.backgroundColor = 'yellow';
  359. t.style.backgroundImage = 'url(images/arrow/arrow-right.png)';
  360. });
  361. rightEl.on('mouseout', function(e) {
  362. var t = e.getTarget();
  363. t.style.backgroundColor = '#EEEEEE';
  364. t.style.backgroundImage = '';
  365. });
  366. rightEl.on('click', function(e) {
  367. Ext.fly('__gef_jbs__').setWidth(Ext.fly('__gef_jbs__').getWidth() + 100);
  368. Ext.fly('__gef_jbs_center__').setWidth(Ext.fly('__gef_jbs_center__').getWidth() + 100);
  369. Ext.fly('__gef_jbs_bottom__').setWidth(Ext.fly('__gef_jbs_bottom__').getWidth() + 100);
  370. Gef.activeEditor.addWidth(100);
  371. });
  372. var bottomEl = Ext.fly('__gef_jbs_bottom__');
  373. bottomEl.on('mouseover', function(e) {
  374. var t = e.getTarget();
  375. t.style.backgroundColor = 'yellow';
  376. t.style.backgroundImage = 'url(images/arrow/arrow-bottom.png)';
  377. });
  378. bottomEl.on('mouseout', function(e) {
  379. var t = e.getTarget();
  380. t.style.backgroundColor = '#EEEEEE';
  381. t.style.backgroundImage = '';
  382. });
  383. rightEl.on('click', function(e) {
  384. Ext.fly('__gef_jbs__').setHeight(Ext.fly('__gef_jbs__').getHeight() + 100);
  385. Ext.fly('__gef_jbs_center__').setHeight(Ext.fly('__gef_jbs_center__').getHeight() + 100);
  386. Ext.fly('__gef_jbs_right__').setHeight(Ext.fly('__gef_jbs_right__').getHeight() + 100);
  387. Gef.activeEditor.addHeight(100);
  388. });
  389. this.body.on('contextmenu', this.onContextMenu, this);
  390. },
  391. onContextMenu: function(e) {
  392. if (!this.contextMenu) {
  393. this.contextMenu = new Ext.menu.Menu({
  394. items: [{
  395. text: '详细配置',
  396. iconCls: 'tb-prop',
  397. handler: this.showWindow,
  398. scope: this
  399. }, {
  400. text: '删除',
  401. iconCls: 'tb-remove',
  402. handler: this.removeSelected,
  403. scope: this
  404. }]
  405. });
  406. }
  407. e.preventDefault();
  408. this.contextMenu.showAt(e.getXY());
  409. },
  410. showWindow: function() {
  411. App.propertyManager.changePropertyStatus('max');
  412. },
  413. removeSelected: function() {
  414. var viewer = Gef.activeEditor.getGraphicalViewer();
  415. var browserListener = viewer.getBrowserListener();
  416. var selectionManager = browserListener.getSelectionManager();
  417. var edge = selectionManager.selectedConnection;
  418. var nodes = selectionManager.items;
  419. var request = {};
  420. if (edge != null) {
  421. request.role = {
  422. name: 'REMOVE_EDGE'
  423. };
  424. this.executeCommand(edge, request);
  425. selectionManager.removeSelectedConnection();
  426. } else if (nodes.length > 0) {
  427. request.role = {
  428. name: 'REMOVE_NODES',
  429. nodes: nodes
  430. };
  431. this.executeCommand(viewer.getContents(), request);
  432. selectionManager.clearAll();
  433. }
  434. },
  435. executeCommand: function(editPart, request) {
  436. var command = editPart.getCommand(request);
  437. if (command != null) {
  438. Gef.activeEditor.getGraphicalViewer().getEditDomain().getCommandStack().execute(command);
  439. }
  440. }
  441. });
  442. /*
  443. * Compressed by JSA(www.xidea.org)
  444. */
  445. Layout = function(editor) {
  446. this.editor = editor;
  447. this.processEditPart = editor.getGraphicalViewer().getContents();
  448. this.processModel = this.processEditPart.getModel();
  449. };
  450. Layout.prototype = {
  451. doLayout: function() {
  452. var diagram = new Diagram();
  453. diagram.init(this.processModel);
  454. var sorter = new TopologicalSorter(diagram);
  455. var sortedElements = sorter.getSortedElements();
  456. var sortedIds = [];
  457. for (var i = 0; i < sortedElements.length; i++) {
  458. sortedIds.push(sortedElements[i].id);
  459. }
  460. //console.info(sortedIds);
  461. var layouter = new LeftToRightGridLayouter(diagram, sortedIds);
  462. layouter.doLayout();
  463. var edgeMap = diagram.getEdgeMap();
  464. for (var edgeId in edgeMap) {
  465. var edge = edgeMap[edgeId];
  466. new EdgeLayouter(layouter.grid, edge);
  467. }
  468. diagram.updateModel();
  469. }
  470. };
  471. ;
  472. Diagram = function() {
  473. };
  474. Diagram.prototype = {
  475. getNodeMap: function() {
  476. return this.nodeMap;
  477. },
  478. getEdgeMap: function() {
  479. return this.edgeMap;
  480. },
  481. init: function(process) {
  482. this.process = process;
  483. this.nodeMap = {};
  484. this.edgeMap = {};
  485. for (var i = 0; i < this.process.children.length; i++) {
  486. var child = process.children[i];
  487. var node = new Node();
  488. node.id = child.text;
  489. node.type = child.type;
  490. node.x = child.x;
  491. node.y = child.y;
  492. node.w = child.w;
  493. node.h = child.h;
  494. this.nodeMap[node.id] = node;
  495. }
  496. for (var i = 0; i < this.process.children.length; i++) {
  497. var child = process.children[i];
  498. for (var j = 0; j < child.getOutgoingConnections().length; j++) {
  499. var connection = child.getOutgoingConnections()[j];
  500. this.createEdge(connection);
  501. }
  502. }
  503. },
  504. createEdge: function(connection) {
  505. var connectionId = connection.getSource().text + '_' + connection.getTarget().text;
  506. var edge = this.edgeMap[connectionId];
  507. if (!edge) {
  508. edge = new Edge();
  509. edge.id = connectionId;
  510. edge.name = connection.text;
  511. edge.source = this.nodeMap[connection.getSource().text];
  512. edge.target = this.nodeMap[connection.getTarget().text];
  513. edge.source.outgoingLinks.push(edge);
  514. edge.target.incomingLinks.push(edge);
  515. this.edgeMap[connectionId] = edge;
  516. }
  517. },
  518. updateModel: function() {
  519. for (var nodeId in this.nodeMap) {
  520. var item = this.nodeMap[nodeId];
  521. var model = this.getModel(nodeId);
  522. model.x = item.x;
  523. model.y = item.y;
  524. model.getEditPart().getFigure().x = model.x;
  525. model.getEditPart().getFigure().y = model.y;
  526. for (var i = 0; i < item.outgoingLinks.length; i++) {
  527. var connection = item.outgoingLinks[i];
  528. var connectionModel = this.getConnectionModel(model, connection);
  529. if (connectionModel == null) {
  530. continue;
  531. }
  532. connectionModel.innerPoints = typeof connection.innerPoints == 'undefined' ? []
  533. : connection.innerPoints;
  534. connectionModel.textX = 0;
  535. connectionModel.textY = 0;
  536. connectionModel.getEditPart().getFigure().innerPoints = connectionModel.innerPoints;
  537. connectionModel.getEditPart().getFigure().textX = connectionModel.textX;
  538. connectionModel.getEditPart().getFigure().textY = connectionModel.textY;
  539. }
  540. }
  541. this.process.getEditPart().refresh();
  542. },
  543. getModel: function(name) {
  544. var model = null;
  545. Gef.each(this.process.children, function(item) {
  546. if (item.text == name) {
  547. model = item;
  548. return false;
  549. }
  550. });
  551. return model;
  552. },
  553. getConnectionModel: function(nodeModel, edge) {
  554. var model = null;
  555. Gef.each(nodeModel.getOutgoingConnections(), function(item) {
  556. if (item.getTarget().text == edge.getTarget().id) {
  557. model = item;
  558. return false;
  559. }
  560. });
  561. return model;
  562. }
  563. };
  564. ;
  565. // should be change name to LayoutingElement
  566. Node = function() {
  567. this.incomingLinks = [];
  568. this.outgoingLinks = [];
  569. };
  570. Node.prototype = {
  571. getIncomingLinks: function() {
  572. return this.incomingLinks;
  573. },
  574. getOutgoingLinks: function() {
  575. return this.outgoingLinks;
  576. },
  577. getPrecedingElements: function() {
  578. var previousElements = [];
  579. for (var i = 0; i < this.incomingLinks.length; i++) {
  580. previousElements.push(this.incomingLinks[i].source);
  581. }
  582. return previousElements;
  583. },
  584. getFollowingElements: function() {
  585. var followingElements = [];
  586. for (var i = 0; i < this.outgoingLinks.length; i++) {
  587. followingElements.push(this.outgoingLinks[i].target);
  588. }
  589. return followingElements;
  590. },
  591. isJoin: function() {
  592. return this.incomingLinks.length > 1;
  593. },
  594. isSplit: function() {
  595. return this.outgoingLinks.length > 1;
  596. },
  597. prevSplit: function() {
  598. var distance = 1000;
  599. var candidateDistance = 0;
  600. var split = null;
  601. var candidate = null;
  602. var precedingElements = this.getPrecedingElements();
  603. for (var i = 0; i < precedingElements.length; i++) {
  604. var elem = precedingElements[i];
  605. if (elem.isSplit()) {
  606. return elem;
  607. }
  608. candidate = elem.prevSplit();
  609. if (this.isJoin()) {
  610. // if this is not a join, we have only one precedingElement.
  611. candidateDistance = elem.backwardDistanceTo(candidate);
  612. }
  613. if (candidateDistance < distance) {
  614. split = candidate;
  615. distance = candidateDistance;
  616. }
  617. }
  618. return split;
  619. },
  620. backwardDistanceTo: function(other) {
  621. return this._backwardDistanceTo(other, []);
  622. },
  623. _backwardDistanceTo: function(other, historyElements) {
  624. if (other == this) {
  625. return 0;
  626. }
  627. if (historyElements.indexOf(this) != -1) {
  628. return 1000;
  629. }
  630. var d = 1000;
  631. var newHistory = [];
  632. newHistory.push(this);
  633. var precedingElements = this.getPrecedingElements();
  634. for (var i = 0; i < precedingElements.length; i++) {
  635. var el = precedingElements[i];
  636. d = Math.min(d, el._backwardDistanceTo(other, newHistory));
  637. }
  638. return d == 1000 ? d : d + 1;
  639. }
  640. };
  641. ;
  642. Edge = function() {
  643. this.source = null;
  644. this.target = null;
  645. };
  646. Edge.prototype = {
  647. getSource: function() {
  648. return this.source;
  649. },
  650. getTarget: function() {
  651. return this.target;
  652. },
  653. reverseOutgoingAndIncoming: function() {
  654. var index = 0;
  655. var oldSource = this.source;
  656. var oldTarget = this.target;
  657. index = oldSource.outgoingLinks.indexOf(this);
  658. oldSource.outgoingLinks.splice(index, 1);
  659. index = oldTarget.incomingLinks.indexOf(this);
  660. oldTarget.incomingLinks.splice(index, 1);
  661. var newSource = oldTarget;
  662. var newTarget = oldSource;
  663. newSource.outgoingLinks.push(this);
  664. newTarget.incomingLinks.push(this);
  665. this.source = newSource;
  666. this.target = newTarget;
  667. }
  668. };
  669. ;
  670. TopologicalSorter = function(diagram) {
  671. this.diagram = diagram;
  672. this.prepareDataAndSort(true);
  673. this.prepareDataAndSort(false);
  674. };
  675. TopologicalSorter.prototype = {
  676. getSortedElements: function() {
  677. return this.sortedElements;
  678. },
  679. prepareDataAndSort: function(shouldBackpatch) {
  680. this.sortedElements = [];
  681. this.elementsToSort = {};
  682. this.backwardsEdges = [];
  683. this.elementsToSortCount = 0;
  684. this.addAllChildren();
  685. this.topologicalSort();
  686. if (shouldBackpatch === true) {
  687. this.backpatchBackwardsEdges();
  688. }
  689. this.reverseBackwardsEdges();
  690. },
  691. addAllChildren: function() {
  692. for (var nodeId in this.diagram.nodeMap) {
  693. var node = this.diagram.nodeMap[nodeId];
  694. this.elementsToSort[nodeId] = new SortableLayoutingElement(node);
  695. this.elementsToSortCount++;
  696. }
  697. },
  698. topologicalSort: function() {
  699. var count = 0;
  700. var oldCount = 0;
  701. while (this.elementsToSortCount > 0) {
  702. var freeElements = this.getFreeElements();
  703. if (freeElements.length > 0) {
  704. for (var i = 0; i < freeElements.length; i++) {
  705. var freeElement = freeElements[i];
  706. this.sortedElements.push(freeElement.node);
  707. this.freeElementsFrom(freeElement);
  708. delete this.elementsToSort[freeElement.node.id];
  709. }
  710. } else {
  711. var entry = this.getLoopEntryPoint();
  712. for (var i = 0; i < entry.incomingLinks.length; i++) {
  713. var backId = entry.incomingLinks[i];
  714. entry.reverseIncomingLinkFrom(backId);
  715. var elem = this.elementsToSort[backId];
  716. elem.reverseOutgoingLinkTo(entry.node.id);
  717. this.backwardsEdges.push(new BackwardsEdge(backId, entry.node.id));
  718. }
  719. }
  720. }
  721. },
  722. backpatchBackwardsEdges: function() {
  723. var newBackwardsEdges = [];
  724. for (var i = 0; i < this.backwardsEdges.length; i++) {
  725. newBackwardsEdges.push(this.backwardsEdges[i]);
  726. }
  727. for (var i = 0; i < this.backwardsEdges.length; i++) {
  728. var edge = this.backwardsEdges[i];
  729. var sourceId = edge.getSource();
  730. var targetId = edge.getTarget();
  731. var sourceElement = this.diagram.nodeMap[sourceId];
  732. while (!(sourceElement.isJoin() || sourceElement.isSplit())) {
  733. var newSourceElement = sourceElement.getPrecedingElements()[0];
  734. targetId = newSourceElement.id;
  735. newBackwardsEdges.push(new BackwardsEdge(targetId, sourceId));
  736. sourceElement = newSourceElement;
  737. sourceId = targetId;
  738. }
  739. }
  740. this.backwardsEdges = newBackwardsEdges;
  741. },
  742. reverseBackwardsEdges: function() {
  743. var edgeMap = this.diagram.edgeMap;
  744. for (var i = 0; i < this.backwardsEdges.length; i++) {
  745. var backwardsEdge = this.backwardsEdges[i];
  746. var sourceId = backwardsEdge.getSource();
  747. var targetId = backwardsEdge.getTarget();
  748. var sourceElement = this.diagram.nodeMap[sourceId];
  749. var targetElement = this.diagram.nodeMap[targetId];
  750. var edge = this.getEdge(edgeMap, sourceElement, targetElement);
  751. backwardsEdge.setEdge(edge);
  752. if (edge) {
  753. // reverse edge outgoing and incoming
  754. edge.reverseOutgoingAndIncoming();
  755. }
  756. }
  757. },
  758. getFreeElements: function() {
  759. var freeElements = [];
  760. for (var nodeId in this.elementsToSort) {
  761. var elem = this.elementsToSort[nodeId];
  762. if (elem.isFree()) {
  763. freeElements.push(elem);
  764. }
  765. }
  766. return freeElements;
  767. },
  768. freeElementsFrom: function(freeElement) {
  769. for (var i = 0; i < freeElement.outgoingLinks.length; i++) {
  770. var id = freeElement.outgoingLinks[i];
  771. var targetElement = this.elementsToSort[id];
  772. if (targetElement) {
  773. targetElement.removeIncomingLinkFrom(freeElement.node.id);
  774. }
  775. }
  776. this.elementsToSortCount--;
  777. },
  778. getLoopEntryPoint: function() {
  779. for (var nodeId in this.elementsToSort) {
  780. var candidate = this.elementsToSort[nodeId];
  781. if (candidate.oldInCount > 1
  782. && candidate.oldInCount > candidate.incomingLinks.length) {
  783. return candidate;
  784. }
  785. }
  786. throw new Error('Could not find a valid loop entry point');
  787. },
  788. getEdge: function(edgeMap, sourceElement, targetElement) {
  789. for (var i = 0; i < sourceElement.outgoingLinks.length; i++) {
  790. var edge = sourceElement.outgoingLinks[i];
  791. if (edge.getTarget().id == targetElement.id) {
  792. return edge;
  793. }
  794. }
  795. return null;
  796. }
  797. };
  798. ;
  799. SortableLayoutingElement = function(node) {
  800. this.node = node;
  801. this.incomingLinks = [];
  802. this.outgoingLinks = [];
  803. for (var i = 0; i < node.incomingLinks.length; i++) {
  804. this.incomingLinks.push(node.incomingLinks[i].source.id);
  805. }
  806. for (var i = 0; i < node.outgoingLinks.length; i++) {
  807. this.outgoingLinks.push(node.outgoingLinks[i].target.id);
  808. }
  809. this.oldInCount = this.incomingLinks.length;
  810. this.isJoin = node.isJoin();
  811. };
  812. SortableLayoutingElement.prototype = {
  813. isFree: function() {
  814. return this.incomingLinks.length == 0;
  815. },
  816. removeIncomingLinkFrom: function(sourceId) {
  817. var index = this.incomingLinks.indexOf(sourceId);
  818. this.incomingLinks.splice(index, 1);
  819. },
  820. reverseIncomingLinkFrom: function(id) {
  821. this.removeIncomingLinkFrom(id);
  822. this.outgoingLinks.push(id);
  823. },
  824. reverseOutgoingLinkTo: function(id) {
  825. var index = this.outgoingLinks.indexOf(id);
  826. this.outgoingLinks.splice(index, 1);
  827. this.incomingLinks.push(id);
  828. }
  829. };
  830. ;
  831. BackwardsEdge = function(source, target) {
  832. this.source = source;
  833. this.target = target;
  834. };
  835. BackwardsEdge.prototype = {
  836. getEdge: function() {
  837. return this.edge;
  838. },
  839. setEdge: function(edge) {
  840. this.edge = edge;
  841. },
  842. getSource: function() {
  843. return this.source;
  844. },
  845. getTarget: function() {
  846. return this.target;
  847. }
  848. };
  849. ;
  850. LeftToRightGridLayouter = function(diagram, sortedIds) {
  851. this.diagram = diagram;
  852. this.sortedIds = sortedIds;
  853. };
  854. LeftToRightGridLayouter.prototype = {
  855. doLayout: function() {
  856. this.grid = new Grid();
  857. this.layoutElements();
  858. this.calcGeometry(this.grid);
  859. this.writeGeometry(this.grid);
  860. this.diagram.updateModel();
  861. },
  862. layoutElements: function() {
  863. for (var i = 0; i < this.sortedIds.length; i++) {
  864. var sortedId = this.sortedIds[i];
  865. var currentElement = this.diagram.nodeMap[sortedId];
  866. var precedingElements = currentElement.getPrecedingElements();
  867. var cellOfElement = this.placeElement(currentElement, precedingElements);
  868. if (currentElement.isJoin() && precedingElements.length != 0) {
  869. // there is an edge hitting us left, so lets forbid
  870. // interleaving to use the left cell, if this is empty
  871. cellOfElement.getPrevCell().setPackable(false);
  872. }
  873. if (currentElement.isSplit()) {
  874. this.prelayoutSuccessors(currentElement, cellOfElement);
  875. }
  876. }
  877. },
  878. placeElement: function(currentElement, precedingElements) {
  879. var newCell = null;
  880. if (precedingElements.length == 0) {
  881. this.grid.startCell.value = currentElement;
  882. newCell = this.grid.startCell;
  883. } else {
  884. var leftCell = null;
  885. var newCell = this.grid.getCellOfItem(currentElement);
  886. if (currentElement.isJoin()) {
  887. var splitFound = false;
  888. var split = currentElement.prevSplit();
  889. if (split != null) {
  890. var splits = new PriorityQueue(currentElement);
  891. splits.add(split);
  892. for (var i = 0; i < precedingElements.length; i++) {
  893. var elem = precedingElements[i];
  894. split = elem.prevSplit();
  895. if (split != null && !splits.contains(split)) {
  896. splits.add(split);
  897. //console.info(splits.items);
  898. }
  899. }
  900. split = null;
  901. // get split with most connections
  902. var maxCon = 0;
  903. for (var i = 0; i < splits.items.length; i++) {
  904. var target = splits.items[i];
  905. if (target == currentElement) {
  906. continue;
  907. }
  908. // current connections
  909. var curCon = 0;
  910. for (var j = 0; j < precedingElements.length; j++) {
  911. var elem = precedingElements[j];
  912. if (elem.backwardDistanceTo(target) < 1000) {
  913. curCon++;
  914. }
  915. }
  916. if (curCon > maxCon) {
  917. maxCon = curCon;
  918. split = target;
  919. }
  920. }
  921. splitFound = split != null;
  922. }
  923. // current cell position
  924. var x = 0;
  925. var yAcc = 0;
  926. var yCnt = 0;
  927. for (var i = 0; i < precedingElements.length; i++) {
  928. var elem = precedingElements[i];
  929. var tmp = this.grid.getCellOfItem(elem);
  930. if (tmp == null) {
  931. tmp = {
  932. getColIndex: function() {
  933. return 0;
  934. }
  935. };
  936. } else {
  937. yAcc += tmp.getRowIndex();
  938. yCnt++;
  939. }
  940. x = Math.max(x, tmp.getColIndex());
  941. }
  942. // farthest to the right
  943. if (splitFound) {
  944. leftCell = this.grid.getCellOfItem(split).row.cells[x];
  945. // set path to split unpackable
  946. for (var c = leftCell; c.value != split; c = c.getPrevCell()) {
  947. c.setPackable(false);
  948. }
  949. } else {
  950. if (yCnt == 0) {
  951. leftCell = this.grid.rows[0].above().cells[x];
  952. } else {
  953. leftCell = this.grid.rows[yAcc / yCnt].cells[x];
  954. }
  955. }
  956. if (newCell != null && newCell.value == currentElement) {
  957. newCell.value = null;
  958. }
  959. newCell = leftCell.after();
  960. // set all incoming pathes unpackable
  961. for (var i = 0; i < precedingElements.length; i++) {
  962. var el = precedingElements[i];
  963. var target = this.grid.getCellOfItem(el);
  964. if (target == null) {
  965. continue;
  966. }
  967. var start = target.row.cells[x + 1];
  968. for (var c = start; c != target; c = c.getPrevCell()) {
  969. c.setPackable(false);
  970. }
  971. }
  972. } else if (newCell == null) {
  973. // if not preLayouted
  974. var preElem = precedingElements[0];
  975. leftCell = this.grid.getCellOfItem(preElem);
  976. newCell = leftCell.after();
  977. }
  978. if (newCell.isFilled() && newCell.value != currentElement) {
  979. newCell.row.insertRowBeneath();
  980. newCell = newCell.beneath();
  981. }
  982. newCell.value = currentElement;
  983. newCell.getPrevCell().setPackable(false);
  984. }
  985. return newCell;
  986. },
  987. prelayoutSuccessors: function(currentElement, cellOfElement) {
  988. var baseCell = cellOfElement.after();
  989. var topCell = baseCell;
  990. var followingElements = currentElement.getFollowingElements();
  991. // heuristic for direct connection to join
  992. var directJoin = null;
  993. for (var i = 0; i < followingElements.length; i++) {
  994. var possibleJoin = followingElements[i];
  995. if (possibleJoin.isJoin()) {
  996. directJoin = possibleJoin;
  997. }
  998. }
  999. if (directJoin != null) {
  1000. // put in the middle
  1001. var index = followingElements.indexOf(directJoin);
  1002. // remove
  1003. followingElements.splice(index, 1);
  1004. var position = parseInt(followingElements.length / 2, 10);
  1005. // insert
  1006. followingElements.splice(position, 0, directJoin);
  1007. }
  1008. // normal preLayout following elements
  1009. var follow = parseInt(followingElements.length / 2, 10);
  1010. for (var i = 0; i < follow; i++) {
  1011. topCell.row.insertRowAbove();
  1012. baseCell.row.insertRowBeneath();
  1013. topCell = topCell.above();
  1014. }
  1015. for (var i = 0; i < followingElements.length; i++) {
  1016. var newElem = followingElements[i];
  1017. if (this.grid.getCellOfItem(newElem)) {
  1018. continue;
  1019. }
  1020. topCell.value = newElem;
  1021. topCell = topCell.beneath();
  1022. if (topCell == baseCell && followingElements.length % 2 == 0) {
  1023. topCell = topCell.beneath();
  1024. }
  1025. }
  1026. },
  1027. calcGeometry: function(grid) {
  1028. grid.pack();
  1029. var heightOfRow = [];
  1030. for (var i = 0; i < grid.rowCount; i++) {
  1031. heightOfRow.push(0);
  1032. }
  1033. var widthOfColumn = [];
  1034. for (var i = 0; i < grid.colCount; i++) {
  1035. widthOfColumn.push(0);
  1036. }
  1037. for (var i = 0; i < grid.rowCount; i++) {
  1038. var row = grid.rows[i];
  1039. for (var j = 0; j < grid.colCount; j++) {
  1040. var cell = row.cells[j];
  1041. if (cell.isFilled()) {
  1042. var elem = cell.value;
  1043. widthOfColumn[j] = Math.max(widthOfColumn[j], elem.w + 30);
  1044. heightOfRow[i] = Math.max(heightOfRow[i], elem.h + 30);
  1045. }
  1046. }
  1047. }
  1048. this.heightOfRow = heightOfRow;
  1049. this.widthOfColumn = widthOfColumn;
  1050. this.totalWidth = 0;
  1051. this.totalHeight = 0;
  1052. for (var i = 0; i < grid.colCount; i++) {
  1053. this.totalWidth += widthOfColumn[i];
  1054. }
  1055. for (var i = 0; i < grid.rowCount; i++) {
  1056. this.totalHeight += heightOfRow[i];
  1057. }
  1058. },
  1059. writeGeometry: function(grid) {
  1060. var x = 0;
  1061. var y = 0;
  1062. for (var i = 0; i < grid.rowCount; i++) {
  1063. var row = grid.rows[i];
  1064. var cellHeight = this.heightOfRow[i];
  1065. for (var j = 0; j < grid.colCount; j++) {
  1066. var cell = row.cells[j];
  1067. var cellWidth = this.widthOfColumn[j];
  1068. if (cell.isFilled()) {
  1069. var elem = cell.value;
  1070. var newX = x + cellWidth / 2 - elem.w / 2;
  1071. var newY = y + cellHeight / 2 - elem.h / 2;
  1072. elem.x = newX;
  1073. elem.y = newY;
  1074. }
  1075. x += cellWidth;
  1076. }
  1077. x = 0;
  1078. y += cellHeight;
  1079. }
  1080. }
  1081. };
  1082. ;
  1083. Grid = function() {
  1084. var cell = new Cell();
  1085. var row = new Row();
  1086. row.grid = this;
  1087. row.addCell(cell);
  1088. this.rows = [row];
  1089. this.startCell = cell;
  1090. this.colCount = 1;
  1091. this.rowCount = this.rows.length;
  1092. };
  1093. Grid.prototype = {
  1094. addFirstRow: function() {
  1095. var row = new Row();
  1096. row.grid = this;
  1097. for (var i = 0; i < this.rolCount; i++) {
  1098. var cell = new Cell();
  1099. row.addCell(cell);
  1100. }
  1101. this.rows.unshift(row);
  1102. this.rowCount = this.rows.length;
  1103. },
  1104. addLastRow: function() {
  1105. var row = new Row();
  1106. row.grid = this;
  1107. for (var i = 0; i < this.rolCount; i++) {
  1108. row.addCell(new Cell());
  1109. }
  1110. this.rows.push(row);
  1111. this.rowCount = this.rows.length;
  1112. },
  1113. addLastCol: function() {
  1114. for (var i = 0; i < this.rowCount; i++) {
  1115. var row = this.rows[i];
  1116. row.addCell(new Cell());
  1117. }
  1118. this.colCount++;
  1119. },
  1120. getCellOfItem: function(elem) {
  1121. for (var i = 0; i < this.rowCount; i++) {
  1122. var row = this.rows[i];
  1123. for (var j = 0; j < this.colCount; j++) {
  1124. var cell = row.cells[j];
  1125. if (cell.value == elem) {
  1126. return cell;
  1127. }
  1128. }
  1129. }
  1130. return null;
  1131. },
  1132. pack: function() {
  1133. var changed = false;
  1134. do {
  1135. changed = false;
  1136. for (var i = 0; i < this.rows.length; i++) {
  1137. var row = this.rows[i];
  1138. changed |= row.tryInterleaveWith(row.getPrevRow());
  1139. }
  1140. for (var i = 0; i < this.rows.length; i++) {
  1141. var row = this.rows[i];
  1142. changed |= row.tryInterleaveWith(row.getNextRow());
  1143. }
  1144. } while (changed);
  1145. },
  1146. info: function() {
  1147. var value = '';
  1148. for (var i = 0; i < this.rows.length; i++) {
  1149. var row = this.rows[i];
  1150. for (var j = 0; j < row.cells.length; j++) {
  1151. var cell = row.cells[j];
  1152. var id = '[ ]';
  1153. if (cell.isFilled()) {
  1154. id = cell.value.id;
  1155. } else if (cell.packable === false) {
  1156. id = '[ p ]';
  1157. }
  1158. value += id;
  1159. }
  1160. value += '\n'
  1161. }
  1162. return value;
  1163. }
  1164. };
  1165. ;
  1166. Cell = function() {
  1167. this.packable = true;
  1168. };
  1169. Cell.prototype = {
  1170. isFilled: function() {
  1171. return typeof this.value != 'undefined' && this.value != null;
  1172. },
  1173. isUnpackable: function() {
  1174. return this.isFilled() || (this.packable === false);
  1175. },
  1176. setPackable: function(packable) {
  1177. this.packable = packable;
  1178. },
  1179. getRowIndex: function() {
  1180. return this.row.getIndex();
  1181. },
  1182. getColIndex: function() {
  1183. for (var i = 0; i < this.row.cells.length; i++) {
  1184. if (this.row.cells[i] == this) {
  1185. return i;
  1186. }
  1187. }
  1188. },
  1189. after: function() {
  1190. var colIndex = this.getColIndex();
  1191. if (colIndex == this.row.cells.length - 1) {
  1192. this.grid.addLastCol();
  1193. }
  1194. return this.row.cells[colIndex + 1];
  1195. },
  1196. above: function() {
  1197. var rowIndex = this.getRowIndex();
  1198. var colIndex = this.getColIndex();
  1199. if (rowIndex == 0) {
  1200. this.row.insertRowAbove();
  1201. }
  1202. return this.grid.rows[rowIndex - 1].cells[colIndex];
  1203. },
  1204. beneath: function() {
  1205. var rowIndex = this.getRowIndex();
  1206. var colIndex = this.getColIndex();
  1207. if (rowIndex == this.grid.rowCount - 1) {
  1208. this.row.insertRowBeneath();
  1209. }
  1210. return this.grid.rows[rowIndex + 1].cells[colIndex];
  1211. },
  1212. getPrevCell: function() {
  1213. var index = this.getColIndex();
  1214. return this.row.cells[index - 1];
  1215. },
  1216. getNextCell: function() {
  1217. var index = this.getColIndex();
  1218. return this.row.cells[index + 1];
  1219. }
  1220. };
  1221. ;
  1222. Row = function() {
  1223. this.cells = [];
  1224. };
  1225. Row.prototype = {
  1226. addCell: function(cell) {
  1227. cell.row = this;
  1228. cell.grid = this.grid;
  1229. this.cells.push(cell);
  1230. },
  1231. getIndex: function() {
  1232. for (var i = 0; i < this.grid.rows.length; i++) {
  1233. if (this.grid.rows[i] == this) {
  1234. return i;
  1235. }
  1236. }
  1237. },
  1238. insertRowBeneath: function() {
  1239. var row = new Row();
  1240. row.grid = this.grid;
  1241. for (var i = 0; i < this.grid.colCount; i++) {
  1242. row.addCell(new Cell());
  1243. }
  1244. var rowIndex = this.getIndex();
  1245. var rows = this.grid.rows;
  1246. if (rowIndex == rows.length - 1) {
  1247. rows.push(row);
  1248. } else {
  1249. rows.splice(rowIndex + 1, 0, row);
  1250. }
  1251. this.grid.rowCount = rows.length;
  1252. },
  1253. insertRowAbove: function() {
  1254. var row = new Row();
  1255. row.grid = this.grid;
  1256. for (var i = 0; i < this.grid.colCount; i++) {
  1257. row.addCell(new Cell());
  1258. }
  1259. var rowIndex = this.getIndex();
  1260. var rows = this.grid.rows;
  1261. if (rowIndex == 0) {
  1262. rows.unshift(row);
  1263. } else {
  1264. rows.splice(rowIndex, 0, row);
  1265. }
  1266. this.grid.rowCount = rows.length;
  1267. },
  1268. getPrevRow: function() {
  1269. var index = this.getIndex();
  1270. if (index > 0) {
  1271. return this.grid.rows[index - 1];
  1272. } else {
  1273. return null;
  1274. }
  1275. },
  1276. getNextRow: function() {
  1277. var index = this.getIndex();
  1278. if (index < this.grid.rows.length) {
  1279. return this.grid.rows[index + 1];
  1280. } else {
  1281. return null;
  1282. }
  1283. },
  1284. tryInterleaveWith: function(other) {
  1285. if (!this.isInterleaveWith(other)) {
  1286. return false;
  1287. }
  1288. for (var i = 0; i < this.cells.length; i++) {
  1289. var cell = this.cells[i];
  1290. var otherCell = other.cells[i];
  1291. if (cell.isFilled()) {
  1292. other.cells[i] = cell;
  1293. } else if (cell.isUnpackable()) {
  1294. otherCell.setPackable(false);
  1295. }
  1296. }
  1297. this._remove();
  1298. return true;
  1299. },
  1300. isInterleaveWith: function(other) {
  1301. if (other == null || other == this) {
  1302. return false;
  1303. } else if (other.getPrevRow() != this && other.getNextRow() != this) {
  1304. return false;
  1305. }
  1306. for (var i = 0; i < this.cells.length; i++) {
  1307. var cell = this.cells[i];
  1308. var otherCell = other.cells[i];
  1309. if (cell.isUnpackable() && otherCell.isUnpackable()) {
  1310. return false;
  1311. }
  1312. }
  1313. return true;
  1314. },
  1315. _remove: function() {
  1316. var index = this.getIndex();
  1317. this.grid.rows.splice(index, 1);
  1318. this.grid.rowCount--;
  1319. }
  1320. };
  1321. ;
  1322. PriorityQueue = function(center) {
  1323. this.ce = center;
  1324. this.items = [];
  1325. };
  1326. PriorityQueue.prototype = {
  1327. add: function(element) {
  1328. this.items.push(element);
  1329. var len = this.items.length;
  1330. for (var i = 0; i < len; i++) {
  1331. for (var j = i; j < len; j++) {
  1332. var elem1 = this.items[i];
  1333. var elem2 = this.items[j];
  1334. if (this.compareTo(elem1, elem2) > 0) {
  1335. this.items[i] = elem2;
  1336. this.items[j] = elem1;
  1337. }
  1338. }
  1339. }
  1340. },
  1341. compareTo: function(elem1, elem2) {
  1342. return this.ce.backwardDistanceTo(elem1) - this.ce.backwardDistanceTo(elem2);
  1343. },
  1344. contains: function(element) {
  1345. return this.items.indexOf(element) != -1;
  1346. }
  1347. };
  1348. ;
  1349. EdgeLayouter = function(grid, edge) {
  1350. this.grid = grid;
  1351. this.edge = edge;
  1352. edge.innerPoints = [];
  1353. this.calculateGlobals();
  1354. this.pickLayoutForEdge();
  1355. };
  1356. EdgeLayouter.prototype = {
  1357. calculateGlobals: function() {
  1358. this.source = this.edge.source;
  1359. this.target = this.edge.target;
  1360. this.sourceRelativeCenterX = this.source.w / 2;
  1361. this.sourceRelativeCenterY = this.source.h / 2;
  1362. this.targetRelativeCenterX = this.target.w / 2;
  1363. this.targetRelativeCenterY = this.target.h / 2;
  1364. this.sourceAbsoluteCenterX = this.source.x + this.sourceRelativeCenterX;
  1365. this.sourceAbsoluteCenterY = this.source.y + this.sourceRelativeCenterY;
  1366. this.targetAbsoluteCenterX = this.target.x + this.targetRelativeCenterX;
  1367. this.targetAbsoluteCenterY = this.target.y + this.targetRelativeCenterY;
  1368. this.sourceAbsoluteX = this.source.x;
  1369. this.sourceAbsoluteY = this.source.y;
  1370. this.sourceAbsoluteX2 = this.source.x + this.source.w;
  1371. this.sourceAbsoluteY2 = this.source.y + this.source.h;
  1372. this.targetAbsoluteX = this.target.x;
  1373. this.targetAbsoluteY = this.target.y;
  1374. this.targetAbsoluteX2 = this.target.x + this.target.w;
  1375. this.targetAbsoluteY2 = this.target.y + this.target.h;
  1376. this.sourceJoin = this.source.isJoin();
  1377. this.sourceSplit = this.source.isSplit();
  1378. this.targetJoin = this.target.isJoin();
  1379. this.targetSplit = this.target.isSplit();
  1380. this.backwards = this.sourceAbsoluteCenterX > this.targetAbsoluteCenterX;
  1381. },
  1382. pickLayoutForEdge: function() {
  1383. // sourceX == targetX, up and down
  1384. if (this.sourceAbsoluteCenterX == this.targetAbsoluteCenterX) {
  1385. this.setEdgeDirectCenter();
  1386. return;
  1387. } else if (this.sourceAbsoluteCenterY == this.targetAbsoluteCenterY) {
  1388. if (this.areCellsHorizontalFree()) {
  1389. this.setEdgeDirectCenter();
  1390. } else {
  1391. this.setEdgeAroundTheCorner(true);
  1392. }
  1393. return;
  1394. }
  1395. if (this.sourceAbsoluteCenterX <= this.targetAbsoluteCenterX
  1396. && this.sourceAbsoluteCenterY <= this.targetAbsoluteCenterY) {
  1397. // target is right under
  1398. if (this.sourcejoin && this.sourceSplit) {
  1399. this.setEdgeStepRight();
  1400. return;
  1401. } else if (this.sourceSplit) {
  1402. this.setEdge90DegreeRightUnderAntiClockwise();
  1403. return;
  1404. } else if (this.targetJoin) {
  1405. this.setEdge90DegreeRightUnderClockwise();
  1406. return;
  1407. }
  1408. } else if (this.sourceAbsoluteCenterX <= this.targetAbsoluteCenterX
  1409. && this.sourceAbsoluteCenterY > this.targetAbsoluteCenterY) {
  1410. // target is right above
  1411. if (this.sourcejoin && this.sourceSplit) {
  1412. this.setEdgeStepRight();
  1413. return;
  1414. } else if (this.sourceSplit) {
  1415. this.setEdge90DegreeRightAboveClockwise();
  1416. return;
  1417. } else if (this.targetJoin) {
  1418. this.setEdge90DegreeRightAboveAntiClockwise();
  1419. return;
  1420. }
  1421. }
  1422. if (this.sourceJoin && sourceSplit && (!this.backwards)) {
  1423. this.setEdgeStepRight();
  1424. return;
  1425. }
  1426. if (this.sourceJoin && sourceSplit) {
  1427. this.setEdgeAroundTheCorner(true);
  1428. return;
  1429. }
  1430. this.setEdgeDirectCenter();
  1431. },
  1432. areCellsHorizontalFree: function() {
  1433. var fromCell = null;
  1434. var toCell = null;
  1435. if (this.sourceAbsoluteCenterX < this.targetAbsoluteCenterX) {
  1436. fromCell = this.grid.getCellOfItem(this.source);
  1437. toCell = this.grid.getCellOfItem(this.target);
  1438. } else {
  1439. fromCell = this.grid.getCellOfItem(this.target);
  1440. toCell = this.grid.getCellOfItem(this.source);
  1441. }
  1442. fromCell = fromCell.getNextCell();
  1443. while (fromCell != toCell) {
  1444. if (fromCell == null || fromCell.isFilled()) {
  1445. return false;
  1446. }
  1447. fromCell = fromCell.getNextCell();
  1448. }
  1449. return true;
  1450. },
  1451. setEdgeDirectCenter: function() {
  1452. var boundsMinX = Math.min(this.sourceAbsoluteCenterX,
  1453. this.targetAbsoluteCenterX);
  1454. var boundsMinY = Math.min(this.sourceAbsoluteCenterY,
  1455. this.targetAbsoluteCenterY);
  1456. var boundsMaxX = Math.max(this.sourceAbsoluteCenterX,
  1457. this.targetAbsoluteCenterX);
  1458. var boundsMaxY = Math.max(this.sourceAbsoluteCenterY,
  1459. this.targetAbsoluteCenterY);
  1460. // this.edge.innerPoints = [];
  1461. },
  1462. setEdge90DegreeRightAboveClockwise: function() {
  1463. this.edge.innerPoints = [
  1464. [this.sourceAbsoluteCenterX, this.targetAbsoluteCenterY]
  1465. ];
  1466. },
  1467. setEdge90DegreeRightAboveAntiClockwise: function() {
  1468. this.edge.innerPoints = [
  1469. [this.targetAbsoluteCenterX, this.sourceAbsoluteCenterY]
  1470. ];
  1471. },
  1472. setEdge90DegreeRightUnderClockwise: function() {
  1473. this.edge.innerPoints = [
  1474. [this.targetAbsoluteCenterX, this.sourceAbsoluteCenterY]
  1475. ];
  1476. },
  1477. setEdge90DegreeRightUnderAntiClockwise: function() {
  1478. this.edge.innerPoints = [
  1479. [this.sourceAbsoluteCenterX, this.targetAbsoluteCenterY]
  1480. ];
  1481. },
  1482. setEdgeAroundTheCorner: function(down) {
  1483. var height = Math.max(this.source.h / 2, this.target.h / 2) + 20;
  1484. if (down) {
  1485. height *= -1;
  1486. }
  1487. this.edge.innerPoints = [
  1488. [this.sourceAbsoluteCenterX, this.sourceAbsoluteCenterY + height],
  1489. [this.targetAbsoluteCenterX, this.sourceAbsoluteCenterY + height]
  1490. ];
  1491. }
  1492. };
  1493. Ext.ux.OneCombo = Ext.extend(Ext.form.ComboBox, {
  1494. initComponent: function() {
  1495. this.readOnly = true;
  1496. this.displayField = 'text';
  1497. this.valueField = 'text';
  1498. this.triggerAction = 'all';
  1499. this.mode = 'local';
  1500. this.emptyText = 'Please Select...';
  1501. this.store = new Ext.data.SimpleStore({
  1502. expandData: true,
  1503. fields: ['text']
  1504. });
  1505. this.store.loadData(this.data);
  1506. Ext.ux.OneCombo.superclass.initComponent.call(this);
  1507. }
  1508. });
  1509. Ext.reg('onecombo', Ext.ux.OneCombo);
  1510. Gef.ns("Gef.planner");
  1511. Gef.ns("Gef.planner.model");
  1512. Gef.ns("Gef.planner.figure");
  1513. Gef.ns("Gef.planner.editpart");
  1514. function registerClass(type, name, url, w, h){
  1515. function capitaliseFirstLetter(string)
  1516. {
  1517. return string.charAt(0).toUpperCase() + string.slice(1);
  1518. }
  1519. var preType = type;
  1520. Gef.planner.model[preType+"Model"] = Gef.extend(Gef.jbs.model.GenericImageModel, {
  1521. type: preType,
  1522. url: url,
  1523. constructor: function(conf) {
  1524. Gef.planner.model[preType+"Model"].superclass.constructor.call(this, conf);
  1525. this.w = w;
  1526. this.h = h;
  1527. }
  1528. });
  1529. Gef.planner.figure[preType+"Figure"] = Gef.extend(Gef.jbs.figure.GenericImageFigure, {
  1530. });
  1531. Gef.planner.editpart[preType+"EditPart"] = Gef.extend(Gef.jbs.editpart.GenericImageEditPart, {
  1532. _figureClassName: "Gef.planner.figure." + preType + "Figure"
  1533. });
  1534. Gef.jbs.JBSModelFactory.registerModel(type, "Gef.planner.model." + preType + "Model");
  1535. Gef.jbs.JBSEditPartFactory.registerEditPart(type, "Gef.planner.editpart." + preType + "EditPart");
  1536. }
  1537. var tpls = [
  1538. ["Yupen", '浴盆', 'images/stenciles/planner/2d/bath.png', 190, 58],
  1539. ["Danrenchuang", '单人床', 'images/stenciles/planner/2d/bed1.png', 243, 163],
  1540. ["Shuangrenchuang", '双人床', 'images/stenciles/planner/2d/bed2.png', 228, 146],
  1541. ["Yizi", '椅子', 'images/stenciles/planner/2d/chair.png', 46, 37],
  1542. ["Shafa1", '沙发1', 'images/stenciles/planner/2d/coach1.png', 123, 51],
  1543. ["Shafa2", '沙发2', 'images/stenciles/planner/2d/coach2.png', 57, 132],
  1544. ["Diannaozhuo", '电脑桌', 'images/stenciles/planner/2d/desk.png', 145, 197],
  1545. ["Canju", '餐具', 'images/stenciles/planner/2d/disc.png', 81,41],
  1546. ["Huapen", '花盆', 'images/stenciles/planner/2d/flowers.png', 95, 60],
  1547. ["Huatai", '花台', 'images/stenciles/planner/2d/flowers2.png', 56, 45],
  1548. ["Xishoupen", '洗手盆', 'images/stenciles/planner/2d/hand.png', 51, 29],
  1549. ["Huxing", '户型', 'images/stenciles/planner/2d/layout.png', 716, 1200],
  1550. ["Canzhuo", '餐桌', 'images/stenciles/planner/2d/table.png', 118, 147],
  1551. ["Matong", '马桶', 'images/stenciles/planner/2d/toilet.png', 78, 42],
  1552. ["Dianshi", '电视', 'images/stenciles/planner/2d/tv.png', 52, 170],
  1553. ["Shuichi", '水池', 'images/stenciles/planner/2d/water.png', 86, 35]
  1554. ];
  1555. (function regClasses(arr){
  1556. for(var i=0;i<tpls.length;i++){
  1557. registerClass.apply(this, tpls[i]);
  1558. }
  1559. })(tpls);
  1560. function makePaletteArray(arr){
  1561. var ret = [
  1562. {name: 'select', image: 'scripts/gef/images/activities/select32.png', title: '选择'},
  1563. {name: 'transition', image: 'scripts/gef/images/activities/32/flow_sequence.png', title: '连线'}
  1564. ];
  1565. for(var i=0;i<tpls.length;i++){
  1566. ret.push({name: tpls[i][0], image: tpls[i][2], title: tpls[i][1]});
  1567. }
  1568. return ret;
  1569. }
  1570. function makeModelArray(arr){
  1571. var ret = {
  1572. select: {
  1573. text: 'select',
  1574. creatable: false
  1575. },
  1576. transition: {
  1577. text: 'transition',
  1578. creatable: false,
  1579. isConnection: true
  1580. }
  1581. };
  1582. for(var i=0;i<tpls.length;i++){
  1583. ret[tpls[i][0]] = {
  1584. text: tpls[i][0],
  1585. w: tpls[i][3],
  1586. h: tpls[i][4]
  1587. };
  1588. }
  1589. return ret;
  1590. }
  1591. Gef.jbs.ExtPaletteHelper = Gef.extend(Gef.jbs.JBSPaletteHelper, {
  1592. createSource: function() {
  1593. return makeModelArray();
  1594. },
  1595. getSource: function() {
  1596. if (!this.source) {
  1597. this.source = this.createSource();
  1598. }
  1599. return this.source;
  1600. },
  1601. render: Gef.emptyFn,
  1602. changeActivePalette: function(paletteConfig) {
  1603. var el = null;
  1604. if (this.getActivePalette()) {
  1605. var oldActivePaletteId = this.getActivePalette().text;
  1606. el = document.getElementById(oldActivePaletteId + '-img');
  1607. el.style.border = '';
  1608. }
  1609. this.setActivePalette(paletteConfig);
  1610. el = document.getElementById(paletteConfig.text + '-img');
  1611. el.style.border = '1px dotted black';
  1612. },
  1613. resetActivePalette: function() {
  1614. this.changeActivePalette({
  1615. text: 'select'
  1616. });
  1617. },
  1618. getPaletteConfig: function(p, t) {
  1619. var id = t.parentNode.id;
  1620. if (!id) {
  1621. return null;
  1622. }
  1623. var source = this.getSource();
  1624. var paletteConfig = this.getSource()[id];
  1625. if (!paletteConfig) {
  1626. return null;
  1627. }
  1628. this.changeActivePalette(paletteConfig);
  1629. if (paletteConfig.creatable === false) {
  1630. return null;
  1631. }
  1632. return paletteConfig;
  1633. }
  1634. });
  1635. App.PalettePanel = Ext.extend(Ext.Panel, {
  1636. initComponent: function() {
  1637. this.region = 'west';
  1638. this.title = '图元库';
  1639. this.iconCls = 'tb-activity';
  1640. this.width = 110;
  1641. this.initPalette();
  1642. App.PalettePanel.superclass.initComponent.call(this);
  1643. },
  1644. initPalette: function() {
  1645. var paletteType = null;
  1646. if (!Gef.PALETTE_TYPE) {
  1647. paletteType = 'accordion';
  1648. } else {
  1649. paletteType = Gef.PALETTE_TYPE;
  1650. }
  1651. this.configLayout(paletteType);
  1652. this.configItems(paletteType);
  1653. },
  1654. createHtml: function(array, divId) {
  1655. if (divId) {
  1656. var html = '<div id="' + divId + '" unselectable="on">';
  1657. } else {
  1658. var html = '<div unselectable="on">';
  1659. }
  1660. for (var i = 0; i < array.length; i++) {
  1661. var item = array[i];
  1662. html += '<div id="' + item.name + '" class="paletteItem-' + item.name
  1663. + '" style="text-align:center;font-size:12px;cursor:pointer;" unselectable="on"><img width="32" height="32" id="'
  1664. + item.name + '-img" class="paletteItem-' + item.name
  1665. + '" src="' + item.image + '" unselectable="on"><br>'
  1666. + item.title + '</div>';
  1667. }
  1668. html += '</div>';
  1669. return html;
  1670. },
  1671. /**
  1672. * this.layout = 'accordion';
  1673. */
  1674. configLayout: function(type) {
  1675. if (!type || type == 'plain') {
  1676. //
  1677. } else if (type && type == 'accordion') {
  1678. this.layout = 'accordion';
  1679. }
  1680. },
  1681. configItems: function(type) {
  1682. if (type && type == 'accordion') {
  1683. this.createItemsForAccordion();
  1684. } else if (!type || type == 'plain') {
  1685. this.createItemsForHtml();
  1686. }
  1687. },
  1688. createItemsForAccordion: function() {
  1689. this.id = '__gef_jbs_palette__';
  1690. this.items = [{
  1691. title: '基础图元',
  1692. iconCls: 'tb-activity',
  1693. autoScroll: true,
  1694. html: this.createHtml(makePaletteArray(tpls))
  1695. }, {
  1696. title: '高级图元',
  1697. iconCls: 'tb-activity',
  1698. autoScroll: true,
  1699. html: ''
  1700. }];
  1701. },
  1702. createItemsForHtml: function() {
  1703. this.autoScroll = true;
  1704. this.html = this.createHtml([
  1705. {name: 'select', image: 'select32', title: '选择'},
  1706. {name: 'transition', image: '32/flow_sequence', title: '连线'},
  1707. {name: 'start', image: '32/start_event_empty', title: '开始'},
  1708. {name: 'end', image: '32/end_event_terminate', title: '结束'},
  1709. {name: 'cancel', image: '32/end_event_cancel', title: '取消'},
  1710. {name: 'error', image: '32/end_event_error', title: '错误'},
  1711. {name: 'state', image: '32/task_wait', title: '等待'},
  1712. {name: 'task', image: '32/task_empty', title: '任务'},
  1713. {name: 'decision', image: '32/gateway_exclusive', title: '决策'},
  1714. {name: 'fork', image: '32/gateway_parallel', title: '并行'},
  1715. {name: 'join', image: '32/gateway_parallel', title: '汇聚'},
  1716. {name: 'java', image: '32/task_java', title: 'JAVA'},
  1717. {name: 'script', image: '32/task_java', title: '脚本'},
  1718. {name: 'hql', image: '32/task_hql', title: 'HQL'},
  1719. {name: 'sql', image: '32/task_sql', title: 'SQL'},
  1720. {name: 'mail', image: '32/task_empty', title: '邮件'},
  1721. {name: 'custom', image: '32/task_empty', title: '自定义'},
  1722. {name: 'subProcess', image: '32/task_empty', title: '子流程'},
  1723. {name: 'jms', image: '32/task_empty', title: 'JMS'},
  1724. {name: 'ruleDecision', image: '32/gateway_exclusive', title: '规则决策'},
  1725. {name: 'rules', image: '32/task_empty', title: '规则'},
  1726. {name: 'human', image: '32/task_empty', title: '人工节点'},
  1727. {name: 'auto', image: '32/task_empty', title: '自动节点'},
  1728. {name: 'counter-sign', image: '32/task_empty', title: '会签节点'}
  1729. ], '__gef_jbs_palette__');
  1730. }
  1731. });
  1732. Ext.ux.TwoCombo = Ext.extend(Ext.form.ComboBox, {
  1733. initComponent: function() {
  1734. this.readOnly = true;
  1735. this.displayField = 'text';
  1736. this.valueField = 'value';
  1737. this.triggerAction = 'all';
  1738. this.mode = 'local';
  1739. this.emptyText = 'Please Select...';
  1740. this.store = new Ext.data.SimpleStore({
  1741. fields: ['value', 'text']
  1742. });
  1743. this.store.loadData(this.data);
  1744. Ext.ux.TwoCombo.superclass.initComponent.call(this);
  1745. }
  1746. });
  1747. Ext.reg('twocombo', Ext.ux.TwoCombo);