actionsbuilder.viewer.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
  1. var ActionsBuilder;
  2. (function (ActionsBuilder) {
  3. var Viewer = (function () {
  4. /*
  5. * Constructor
  6. * @param type: the root type object (OBJECT or SCENE)
  7. */
  8. function Viewer(type) {
  9. var _this = this;
  10. this.objectName = "Unnamed Object";
  11. this.zoom = 1.0;
  12. this._firstUpdate = true;
  13. // Get HTML elements
  14. this.viewerContainer = document.getElementById("GraphContainerID");
  15. this.viewerElement = document.getElementById("GraphElementID");
  16. // Create element
  17. this.paper = Raphael("GraphElementID", screen.width, screen.height);
  18. // Configure this
  19. //var name = type === Type.OBJECT ? "Unnamed object" : "Scene";
  20. this.root = this.addAction(null, type, { name: this.objectName, text: this.objectName, properties: [], description: "" });
  21. this.selectedNode = null;
  22. // Configure events
  23. window.addEventListener("resize", function (event) {
  24. _this.onResize(event);
  25. });
  26. window.addEventListener("mousemove", function (event) {
  27. _this.onMove(event);
  28. });
  29. this.paper.canvas.addEventListener("click", function (event) {
  30. _this.onClick(event);
  31. });
  32. // Load modules
  33. this._toolbar = new ActionsBuilder.Toolbar(this);
  34. this._contextMenu = new ActionsBuilder.ContextMenu(this);
  35. this.parameters = new ActionsBuilder.Parameters(this);
  36. this.utils = new ActionsBuilder.Utils(this);
  37. // Finish
  38. this.parameters.parametersHelpElement.textContent = Viewer._DEFAULT_INFO_MESSAGE;
  39. this.onResize(null);
  40. }
  41. Object.defineProperty(Viewer, "NODE_WIDTH", {
  42. get: function () {
  43. return Viewer._NODE_WIDTH;
  44. },
  45. enumerable: true,
  46. configurable: true
  47. });
  48. Object.defineProperty(Viewer, "NODE_HEIGHT", {
  49. get: function () {
  50. return Viewer._NODE_HEIGHT;
  51. },
  52. enumerable: true,
  53. configurable: true
  54. });
  55. Object.defineProperty(Viewer, "NODE_MINIMIZED_WIDTH", {
  56. get: function () {
  57. return Viewer._NODE_MINIMIZE_WIDTH;
  58. },
  59. enumerable: true,
  60. configurable: true
  61. });
  62. Object.defineProperty(Viewer, "VERTICAL_OFFSET", {
  63. get: function () {
  64. return Viewer._VERTICAL_OFFSET;
  65. },
  66. enumerable: true,
  67. configurable: true
  68. });
  69. /*
  70. * Resize event
  71. * @param event: the resize event
  72. */
  73. Viewer.prototype.onResize = function (event) {
  74. var tools = document.getElementById("ToolsButtonsID");
  75. this.viewerContainer.style.height = window.innerHeight - tools.getBoundingClientRect().height - 25 - 50 + "px";
  76. this.viewerElement.style.height = window.innerHeight - tools.getBoundingClientRect().height - 25 - 50 + "px";
  77. this.parameters.onResize();
  78. this._toolbar.onResize();
  79. if (this.paper.height < window.innerHeight) {
  80. this.paper.setSize(this.paper.width, window.innerHeight);
  81. }
  82. if (this._firstUpdate) {
  83. this.viewerElement.scrollLeft = ((this.viewerElement.scrollWidth / 2) - (this.viewerElement.getBoundingClientRect().width / 2));
  84. this._firstUpdate = false;
  85. }
  86. };
  87. /*
  88. * Handles the onMove event
  89. * @param event: the onMove mouse event
  90. */
  91. Viewer.prototype.onMove = function (event) {
  92. this.mousex = event.clientX - this.paper.canvas.getBoundingClientRect().left;
  93. this.mousey = event.clientY - this.paper.canvas.getBoundingClientRect().top;
  94. };
  95. /*
  96. * Handles the onClick event to get selected node
  97. * @param event: the onClick mouse event
  98. */
  99. Viewer.prototype.onClick = function (event) {
  100. if (this._contextMenu.showing) {
  101. return;
  102. }
  103. // Reset selected node
  104. if (this.selectedNode !== null) {
  105. var node = this.selectedNode.node;
  106. node.rect.attr("fill", this.getNodeColor(this.selectedNode.type, node.detached));
  107. }
  108. // Configure new selected node
  109. var result = this.traverseGraph(null, this.mousex, this.mousey, true);
  110. if (result.hit) {
  111. this.selectedNode = result.action;
  112. var node = this.selectedNode.node;
  113. node.rect.attr("fill", this.getSelectedNodeColor(this.selectedNode.type, node.detached));
  114. }
  115. else {
  116. this.selectedNode = null;
  117. this.parameters.clearParameters();
  118. this.parameters.parametersHelpElement.textContent = Viewer._DEFAULT_INFO_MESSAGE;
  119. }
  120. };
  121. /*
  122. * Set the color theme of the viewer
  123. * @param color: the color theme ( ex: "rgb(64, 64, 64)" )
  124. */
  125. Viewer.prototype.setColorTheme = function (color) {
  126. this.paper.canvas.style.background = color;
  127. };
  128. /*
  129. * Returns the color according to the given parameters
  130. * @param action: the action used to select the color
  131. * @param detached: if the node is attached to its parent or not
  132. */
  133. Viewer.prototype.getNodeColor = function (type, detached) {
  134. if (detached) {
  135. return Raphael.rgb(96, 122, 14);
  136. }
  137. switch (type) {
  138. case ActionsBuilder.Type.TRIGGER: return Raphael.rgb(133, 154, 185);
  139. case ActionsBuilder.Type.ACTION: return Raphael.rgb(182, 185, 132);
  140. case ActionsBuilder.Type.FLOW_CONTROL: return Raphael.rgb(185, 132, 140);
  141. case ActionsBuilder.Type.OBJECT:
  142. case ActionsBuilder.Type.SCENE: return Raphael.rgb(255, 255, 255);
  143. default: break;
  144. }
  145. return null;
  146. };
  147. /*
  148. * Returns the selected node color according to the given parameters
  149. * @param action: the action used to select the color
  150. * @param detached: if the node is attached to its parent or not
  151. */
  152. Viewer.prototype.getSelectedNodeColor = function (type, detached) {
  153. if (detached) {
  154. return Raphael.rgb(96, 122, 14);
  155. }
  156. switch (type) {
  157. case ActionsBuilder.Type.TRIGGER: return Raphael.rgb(41, 129, 255);
  158. case ActionsBuilder.Type.ACTION: return Raphael.rgb(255, 220, 42);
  159. case ActionsBuilder.Type.FLOW_CONTROL: return Raphael.rgb(255, 41, 53);
  160. case ActionsBuilder.Type.OBJECT:
  161. case ActionsBuilder.Type.SCENE: return Raphael.rgb(255, 255, 255);
  162. default: break;
  163. }
  164. return null;
  165. };
  166. /*
  167. * Removes the given action from the graph
  168. * @param action: the action to remove
  169. * @param removeChildren: if remove the branch or not
  170. */
  171. Viewer.prototype.removeAction = function (action, removeChildren) {
  172. // If selected node is combine
  173. if (action.parent !== null && action.parent.hub === action) {
  174. this.removeAction(action.parent, false);
  175. return;
  176. }
  177. // Basic suppress
  178. this.removeNode(action.node);
  179. if (action.combineArray !== null) {
  180. this.removeNode(action.hub.node);
  181. // Remove combine array
  182. for (var i = 0; i < action.combineArray.length; i++) {
  183. this.removeNode(action.combineArray[i].node);
  184. }
  185. action.combineArray.length = 0;
  186. }
  187. if (removeChildren) {
  188. for (var i = 0; i < action.children.length; i++) {
  189. this.removeAction(action.children[i], removeChildren);
  190. }
  191. action.clearChildren();
  192. }
  193. else {
  194. for (var i = 0; i < action.children.length; i++) {
  195. action.parent.addChild(action.children[i]);
  196. action.children[i].parent = action.parent;
  197. }
  198. }
  199. };
  200. /*
  201. * Removes the given node (not the action)
  202. * @param node: the node to remove
  203. */
  204. Viewer.prototype.removeNode = function (node) {
  205. node.rect.remove();
  206. node.text.remove();
  207. if (node.line !== null) {
  208. node.line.remove();
  209. }
  210. };
  211. /*
  212. * Updates the graph viewer
  213. */
  214. Viewer.prototype.update = function () {
  215. var _this = this;
  216. // Set root position
  217. this._setActionPosition(this.root, (this.paper.width / 2) - (Viewer.NODE_WIDTH / 2) * this.zoom, 10);
  218. // Sets node size
  219. var onSetNodeSize = function (node) {
  220. node.rect.attr("width", node.minimized ? Viewer.NODE_MINIMIZED_WIDTH : Viewer.NODE_WIDTH * _this.zoom);
  221. node.rect.attr("height", Viewer.NODE_HEIGHT * _this.zoom);
  222. node.text.attr("font-size", 11 * _this.zoom);
  223. };
  224. // First pass: set actions positions according to parents
  225. var onSetPositionPass = function (action, yPosition) {
  226. var node = action.node;
  227. var parent = action.parent !== null ? action.parent : null;
  228. // Set node properties (size, text size, etc.)
  229. if (action.combineArray !== null) {
  230. for (var i = 0; i < action.combineArray.length; i++) {
  231. var combinedNode = action.combineArray[i].node;
  232. onSetNodeSize(combinedNode);
  233. }
  234. }
  235. onSetNodeSize(node);
  236. // Set position from parent
  237. if (parent) {
  238. var parentx = parent.node.rect.attr("x");
  239. if (parent.combineArray !== null && parent.combineArray.length > 1) {
  240. parentx += parent.node.rect.attr("width") / 2;
  241. }
  242. _this._setActionPosition(action, parentx, yPosition);
  243. _this._setActionLine(action);
  244. }
  245. // Calculate total width for current action
  246. var totalSize = 0;
  247. for (var i = 0; i < action.children.length; i++) {
  248. var childNode = action.children[i].node;
  249. totalSize += childNode.rect.attr("width");
  250. }
  251. // Get values to place nodes according to the parent position
  252. var nodeWidth = node.rect.attr("width");
  253. var startingPositionX = node.rect.attr("x");
  254. // Set children positions
  255. for (var i = 0; i < action.children.length; i++) {
  256. var childAction = action.children[i];
  257. var childNode = childAction.node;
  258. var newPositionX = startingPositionX;
  259. if (childAction.combineArray !== null && childAction.combineArray.length > 1) {
  260. newPositionX -= (childNode.rect.attr("width") / 2) - nodeWidth / 2;
  261. }
  262. var newPositionY = yPosition + Viewer.VERTICAL_OFFSET * _this.zoom;
  263. onSetPositionPass(childAction, newPositionY);
  264. _this._setActionPosition(childAction, newPositionX, newPositionY);
  265. _this._setActionLine(childAction);
  266. }
  267. };
  268. onSetPositionPass(this.root, 10 * this.zoom);
  269. // Seconds pass, get sizes of groups
  270. var onGetSizePass = function (action, maxSize) {
  271. var mySize = 0;
  272. if (action.combineArray !== null) {
  273. for (var i = 0; i < action.combineArray.length; i++) {
  274. mySize += action.combineArray[i].node.rect.attr("width");
  275. }
  276. }
  277. else {
  278. mySize = action.node.rect.attr("width");
  279. }
  280. if (mySize > maxSize) {
  281. maxSize = mySize;
  282. }
  283. for (var i = 0; i < action.children.length; i++) {
  284. maxSize = onGetSizePass(action.children[i], maxSize);
  285. }
  286. return maxSize;
  287. };
  288. // Resize canvas
  289. var onResizeCanvas = function (action) {
  290. var node = action.node;
  291. var nodex = node.rect.attr("x");
  292. var nodey = node.rect.attr("y");
  293. if (nodex < 0 || nodex > _this.paper.width) {
  294. _this.paper.setSize(_this.paper.width + 1000, _this.paper.height);
  295. _this._setActionPosition(_this.root, (_this.paper.width / 2) - (Viewer.NODE_WIDTH / 2) * _this.zoom, 10);
  296. }
  297. if (nodey > _this.paper.height) {
  298. _this.paper.setSize(_this.paper.width, _this.paper.height + 1000);
  299. _this._setActionPosition(_this.root, (_this.paper.width / 2) - (Viewer.NODE_WIDTH / 2) * _this.zoom, 10);
  300. }
  301. };
  302. var widths = new Array();
  303. for (var i = 0; i < this.root.children.length; i++) {
  304. var trigger = this.root.children[i];
  305. var triggerResult = { triggerWidth: onGetSizePass(trigger, 0), childrenWidths: new Array() };
  306. if (trigger.children.length > 0) {
  307. triggerResult.triggerWidth = 0;
  308. }
  309. for (var j = 0; j < trigger.children.length; j++) {
  310. var actionWidth = onGetSizePass(trigger.children[j], 0);
  311. triggerResult.triggerWidth += actionWidth + 15;
  312. triggerResult.childrenWidths.push({
  313. triggerWidth: actionWidth,
  314. childrenWidths: null
  315. });
  316. }
  317. widths.push(triggerResult);
  318. }
  319. // Third pass, set positions of nodes
  320. var onSetNodePosition = function (action, widthArray, isChild) {
  321. var actionsCount = action.children.length;
  322. var actionsMiddle = actionsCount % 2;
  323. var actionsHasMiddle = actionsMiddle !== 0;
  324. var actionsLeftOffset = 0;
  325. var actionsRightOffset = 0;
  326. var actionWidth = action.node.rect.attr("width");
  327. if (actionsHasMiddle && actionsCount > 1) {
  328. var middle = Math.floor(actionsCount / 2);
  329. actionsLeftOffset += widthArray[middle].triggerWidth / 2;
  330. actionsRightOffset += widthArray[middle].triggerWidth / 2;
  331. }
  332. // Move left
  333. var leftStart = actionsHasMiddle ? Math.floor(actionsCount / 2) - 1 : (actionsCount / 2) - 1;
  334. for (var i = leftStart; i >= 0; i--) {
  335. var child = action.children[i];
  336. var node = child.node;
  337. var width = (widthArray[i].triggerWidth) + 15;
  338. _this._setActionPosition(action.children[i], node.rect.attr("x") - actionsLeftOffset - (width / 2), node.rect.attr("y"));
  339. _this._setActionLine(child);
  340. onResizeCanvas(child);
  341. actionsLeftOffset += width;
  342. }
  343. // Move right
  344. var rightStart = actionsHasMiddle ? Math.round(actionsCount / 2) : actionsCount / 2;
  345. for (var i = rightStart; i < actionsCount; i++) {
  346. var child = action.children[i];
  347. var node = child.node;
  348. var width = (widthArray[i].triggerWidth) + 15;
  349. _this._setActionPosition(action.children[i], node.rect.attr("x") + actionsRightOffset + (width / 2), node.rect.attr("y"));
  350. _this._setActionLine(child);
  351. onResizeCanvas(child);
  352. actionsRightOffset += width;
  353. }
  354. };
  355. onSetNodePosition(this.root, widths, false);
  356. for (var i = 0; i < this.root.children.length; i++) {
  357. onSetNodePosition(this.root.children[i], widths[i].childrenWidths, true);
  358. }
  359. };
  360. /*
  361. * Adds an action to the graph viewer and returns it
  362. * @param parent: the parent action
  363. * @param type: the action type
  364. * @param element: the Actions Builder type (TRIGGERS, ACTIONS, FLOW_CONTROLS)
  365. */
  366. Viewer.prototype.addAction = function (parent, type, element) {
  367. var node = this._createNode(element.text, type, parent === null);
  368. var action = new ActionsBuilder.Action(node);
  369. if (element.name === "CombineAction") {
  370. action.combineArray = new Array();
  371. var hubElement = ActionsBuilder.Elements.FLOW_CONTROLS[ActionsBuilder.Elements.FLOW_CONTROLS.length - 1];
  372. var hub = this.addAction(action, ActionsBuilder.Type.FLOW_CONTROL, hubElement);
  373. action.hub = hub;
  374. action.addChild(hub);
  375. this._createActionAnimation(hub);
  376. }
  377. action.name = element.name;
  378. action.properties = element.properties;
  379. action.type = type;
  380. // Configure properties
  381. for (var i = 0; i < action.properties.length; i++) {
  382. action.propertiesResults.push({ targetType: action.properties[i].targetType, value: action.properties[i].value });
  383. }
  384. if (action.properties !== null && action.properties.length > 0) {
  385. if (action.properties[0].text === "target") {
  386. action.propertiesResults[0].value = this.objectName;
  387. }
  388. }
  389. if (parent !== null) {
  390. if (parent.combineArray === null) {
  391. parent.addChild(action);
  392. }
  393. else if (parent.combineArray !== null && action.name !== "Hub") {
  394. parent.combineArray.push(action);
  395. action.parent = parent;
  396. action.combineAction = parent;
  397. parent.node.text.attr("text", "");
  398. }
  399. }
  400. // Create animation
  401. this._createActionAnimation(action);
  402. return action;
  403. };
  404. /*
  405. * Traverses the graph viewer and returns if an action
  406. * is selected at coordinates (x, y)
  407. * @param start: the start node. Can be null
  408. * @param x: the x coordinate
  409. * @param y: the y coordinate
  410. * @param traverseCombine: if we traverse combine actions children
  411. */
  412. Viewer.prototype.traverseGraph = function (start, x, y, traverseCombine) {
  413. if (start === null)
  414. start = this.root;
  415. var result = { action: start, hit: true };
  416. if (start.node.isPointInside(x, y)) {
  417. return result;
  418. }
  419. for (var i = 0; i < start.children.length; i++) {
  420. var action = start.children[i];
  421. if (action.node.isPointInside(x, y)) {
  422. result.hit = true;
  423. result.action = start.children[i];
  424. if (traverseCombine && action.combineArray !== null) {
  425. for (var j = 0; j < action.combineArray.length; j++) {
  426. if (action.combineArray[j].node.isPointInside(x, y)) {
  427. result.action = action.combineArray[j];
  428. break;
  429. }
  430. }
  431. }
  432. return result;
  433. }
  434. result = this.traverseGraph(action, x, y, traverseCombine);
  435. if (result.hit) {
  436. return result;
  437. }
  438. }
  439. result.hit = false;
  440. result.action = null;
  441. return result;
  442. };
  443. /*
  444. * Sets the action's position (node)
  445. * @param action: the action to place
  446. * @param x: the x position of the action
  447. * @param y: the y position of the action
  448. */
  449. Viewer.prototype._setActionPosition = function (action, x, y) {
  450. var node = action.node;
  451. var offsetx = node.rect.attr("x") - x;
  452. var parent = action.parent;
  453. if (parent !== null && parent.combineArray !== null && parent.combineArray.length > 1) {
  454. var parentNode = parent.node;
  455. x = parentNode.rect.attr("x") + (parent.node.rect.attr("width") / 2) - (node.rect.attr("width") / 2);
  456. }
  457. node.rect.attr("x", x);
  458. node.rect.attr("y", y);
  459. var textBBox = node.text.getBBox();
  460. var textWidth = 0;
  461. if (textBBox !== null && textBBox !== undefined) {
  462. textWidth = textBBox.width;
  463. }
  464. node.text.attr("x", x + node.rect.attr("width") / 2 - textWidth / 2);
  465. node.text.attr("y", y + node.rect.attr("height") / 2);
  466. if (action.combineArray !== null && action.combineArray.length > 0) {
  467. var length = 0;
  468. for (var i = 0; i < action.combineArray.length; i++) {
  469. var combinedAction = action.combineArray[i];
  470. var combinedNode = combinedAction.node;
  471. combinedNode.rect.attr("x", node.rect.attr("x") + length);
  472. combinedNode.rect.attr("y", node.rect.attr("y"));
  473. textBBox = combinedNode.text.getBBox();
  474. if (textBBox !== null) {
  475. textWidth = textBBox.width;
  476. }
  477. combinedNode.text.attr("x", combinedNode.rect.attr("x") + combinedNode.rect.attr("width") / 2 - textWidth / 2);
  478. combinedNode.text.attr("y", y + combinedNode.rect.attr("height") / 2);
  479. length += combinedNode.rect.attr("width");
  480. }
  481. node.rect.attr("width", length);
  482. }
  483. for (var i = 0; i < action.children.length; i++) {
  484. var child = action.children[i];
  485. this._setActionPosition(child, child.node.rect.attr("x") - offsetx, y + Viewer.VERTICAL_OFFSET * this.zoom);
  486. this._setActionLine(child);
  487. }
  488. };
  489. /*
  490. * Configures the line (link) between the action and its parent
  491. * @param action: the action to configure
  492. */
  493. Viewer.prototype._setActionLine = function (action) {
  494. if (action.node.line === null) {
  495. return;
  496. }
  497. var node = action.node;
  498. var nodex = node.rect.attr("x");
  499. var nodey = node.rect.attr("y");
  500. var nodeWidth = node.rect.attr("width");
  501. var nodeHeight = node.rect.attr("height");
  502. var parent = action.parent.node;
  503. var parentx = parent.rect.attr("x");
  504. var parenty = parent.rect.attr("y");
  505. var parentWidth = parent.rect.attr("width");
  506. var parentHeight = parent.rect.attr("height");
  507. if (node.detached) {
  508. node.line.attr("path", ["M", nodex, nodey, "L", nodex, nodey]);
  509. return;
  510. }
  511. var line1x = nodex + (nodeWidth / 2);
  512. var line1y = nodey;
  513. var line2y = line1y - (line1y - parenty - parentHeight) / 2;
  514. var line3x = parentx + (parentWidth / 2);
  515. var line4y = parenty + parentHeight;
  516. node.line.attr("path", ["M", line1x, line1y, "L", line1x, line2y, "L", line3x, line2y, "L", line3x, line4y]);
  517. };
  518. /*
  519. * Creates and returns a node
  520. * @param text: the text to draw in the nde
  521. * @param color: the node's color
  522. * @param noLine: if draw a line to the parent or not
  523. */
  524. Viewer.prototype._createNode = function (text, type, noLine) {
  525. var node = new ActionsBuilder.Node();
  526. var color = this.getNodeColor(type, false);
  527. node.rect = this.paper.rect(20, 20, Viewer.NODE_WIDTH, Viewer.NODE_HEIGHT, 0);
  528. node.rect.attr("fill", color);
  529. node.text = this.paper.text(20, 20, text);
  530. node.text.attr("font-size", 11);
  531. node.text.attr("text-anchor", "start");
  532. node.text.attr("font-family", "Sinkin Sans Light");
  533. if (!noLine) {
  534. node.line = this.paper.path("");
  535. node.line.attr("stroke", color);
  536. }
  537. return node;
  538. };
  539. /*
  540. * Creates the drag animation
  541. * @param action: the action to animate
  542. */
  543. Viewer.prototype._createActionAnimation = function (action) {
  544. var _this = this;
  545. var node = action.node;
  546. var finished = true;
  547. var nodex = 0;
  548. var nodey = 0;
  549. var onMove = function (dx, dy, x, y) { };
  550. var onStart = function (x, y, event) {
  551. if (node.minimized) {
  552. return;
  553. }
  554. if (finished) {
  555. nodex = node.rect.attr("x");
  556. nodey = node.rect.attr("y");
  557. }
  558. finished = false;
  559. node.rect.animate({
  560. x: node.rect.attr("x") - 10,
  561. y: node.rect.attr("y"),
  562. width: (Viewer.NODE_WIDTH + 20) * _this.zoom,
  563. height: (Viewer.NODE_HEIGHT + 10) * _this.zoom,
  564. opacity: 0.25
  565. }, 500, ">");
  566. };
  567. var onEnd = function (event) {
  568. if (!node.minimized) {
  569. node.rect.animate({
  570. x: nodex,
  571. y: nodey,
  572. width: Viewer.NODE_WIDTH * _this.zoom,
  573. height: Viewer.NODE_HEIGHT * _this.zoom,
  574. opacity: 1.0
  575. }, 500, ">", function () { finished = true; });
  576. }
  577. var dragResult = _this.traverseGraph(null, _this.mousex, _this.mousey, true);
  578. if (dragResult.hit && dragResult.action === action || !dragResult.hit) {
  579. // Create parameters. Action can be null
  580. _this.parameters.createParameters(action);
  581. }
  582. else {
  583. // Manage drag'n'drop
  584. if (dragResult.action.children.length > 0 && action.type !== ActionsBuilder.Type.TRIGGER) {
  585. return;
  586. }
  587. if (action.type === ActionsBuilder.Type.TRIGGER && dragResult.action !== _this.root) {
  588. return;
  589. }
  590. if (action.type === ActionsBuilder.Type.ACTION && dragResult.action === _this.root) {
  591. return;
  592. }
  593. if (action.type === ActionsBuilder.Type.FLOW_CONTROL && (dragResult.action === _this.root || dragResult.action.type === ActionsBuilder.Type.FLOW_CONTROL)) {
  594. return;
  595. }
  596. if (action === dragResult.action.parent) {
  597. return;
  598. }
  599. if (action.parent !== null && action.parent.combineArray !== null) {
  600. return;
  601. }
  602. // Reset node
  603. node.rect.stop(node.rect.animation);
  604. node.text.stop(node.text.animation);
  605. node.rect.undrag();
  606. node.text.undrag();
  607. node.rect.attr("opacity", 1.0);
  608. node.rect.attr("width", Viewer.NODE_WIDTH);
  609. node.rect.attr("height", Viewer.NODE_HEIGHT);
  610. if (action.parent !== null) {
  611. // Configure drag'n'drop
  612. action.parent.removeChild(action);
  613. dragResult.action.addChild(action);
  614. _this.update();
  615. _this._createActionAnimation(action);
  616. }
  617. }
  618. };
  619. node.rect.drag(onMove, onStart, onEnd);
  620. node.text.drag(onMove, onStart, onEnd);
  621. };
  622. return Viewer;
  623. }());
  624. // Statics
  625. Viewer._NODE_WIDTH = 150;
  626. Viewer._NODE_HEIGHT = 25;
  627. Viewer._NODE_MINIMIZE_WIDTH = 50;
  628. Viewer._VERTICAL_OFFSET = 70;
  629. Viewer._DEFAULT_INFO_MESSAGE = "Select or add a node to customize actions";
  630. ActionsBuilder.Viewer = Viewer;
  631. })(ActionsBuilder || (ActionsBuilder = {}));
  632. //# sourceMappingURL=actionsbuilder.viewer.js.map