contextmenu.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /// <reference path="raphael.js" />
  2. /// <reference path="actionKinds.js" />
  3. /// <reference path="viewer.js" />
  4. var AB;
  5. (function (AB) {
  6. var ContextMenu = (function () {
  7. function ContextMenu(viewer) {
  8. var scope = this;
  9. // Members
  10. this.viewer = viewer;
  11. this.showing = false;
  12. this.savedColor = Raphael.rgb(255, 255, 255);
  13. this.overColor = Raphael.rgb(140, 200, 230);
  14. // Context menu elements
  15. this.elements = [
  16. { text: "Reduce", rect: null, action: "onReduce" },
  17. { text: "Delete", rect: null, action: "onRemoveNode" },
  18. { text: "Delete branch", rect: null, action: "onRemoveBranch" },
  19. { text: "Connect / Disconnect", rect: null, action: "onDetachNode" },
  20. { text: "Copy", rect: null, action: "onCopyStructure" },
  21. { text: "Paste", rect: null, action: "onPasteStructure" },
  22. // Add other elements here
  23. { text: "", rect: null, action: null } // Color separator (top)
  24. ];
  25. // Finish
  26. this.attachControl(viewer.graph.canvas);
  27. }
  28. // Attaches controls to the viewer
  29. // element: the viewer element (canvas or div or etc.)
  30. ContextMenu.prototype.attachControl = function (element) {
  31. var scope = this;
  32. var onClick = function (event) {
  33. var x = scope.viewer.mousex;
  34. var y = scope.viewer.mousey;
  35. // Remove all context menu nodes, and run action if selected
  36. if (scope.showing) {
  37. for (var i = 0; i < scope.elements.length; i++) {
  38. var el = scope.elements[i];
  39. if (el.action && el.rect.isPointInside(x, y))
  40. scope.viewer.utils[el.action]();
  41. scope.viewer._removeNode(el.rect);
  42. }
  43. }
  44. scope.showing = false;
  45. };
  46. var onMouseMove = function (event) {
  47. // Override context menu's node color if mouse is inside
  48. if (scope.showing) {
  49. for (var i = 0; i < scope.elements.length; i++) {
  50. var el = scope.elements[i];
  51. if (el.text == "")
  52. continue;
  53. var x = scope.viewer.mousex;
  54. var y = scope.viewer.mousey;
  55. if (el.rect.isPointInside(x, y))
  56. el.rect.attr(el.rect.rect, "fill", scope.overColor);
  57. else
  58. el.rect.attr(el.rect.rect, "fill", scope.savedColor);
  59. }
  60. }
  61. };
  62. var onRightClick = function (event) {
  63. var x = scope.viewer.mousex;
  64. var y = scope.viewer.mousey;
  65. if (y + (AB.Graph.NODE_HEIGHT * scope.elements.length) > scope.viewer.element.offsetHeight + scope.viewer.element.scrollTop)
  66. y = (AB.Graph.NODE_HEIGHT * scope.elements.length);
  67. if (x + AB.Graph.NODE_WIDTH > scope.viewer.element.offsetWidth + scope.viewer.element.scrollLeft)
  68. x -= AB.Graph.NODE_WIDTH;
  69. scope.viewer.onClick(event);
  70. // Set selected node
  71. var result = scope.viewer.traverseGraph(null, x, y);
  72. if (result.hit) {
  73. scope.viewer.selectedNode = result.element;
  74. }
  75. if (!scope.showing) {
  76. if (scope.viewer.selectedNode == null)
  77. return;
  78. // Create elements
  79. var yOffset = 10;
  80. for (var i = 0; i < scope.elements.length - 1; i++) {
  81. var el = scope.elements[i];
  82. el.rect = scope.viewer._createNode(el.text, Raphael.rgb(216, 216, 216), true);
  83. scope.viewer._setNodePosition(el.rect, x, y + yOffset);
  84. el.rect.text.attr("x", x + 5);
  85. yOffset += AB.Graph.NODE_HEIGHT;
  86. }
  87. // Color separator
  88. var separator = scope.elements[scope.elements.length - 1];
  89. separator.rect = scope.viewer._createNode("", scope.viewer.getNodeColor(scope.viewer.selectedNode), true);
  90. scope.viewer._setNodePosition(separator.rect, x, y);
  91. separator.rect.attr(separator.rect.rect, "height", 10);
  92. // Finish
  93. scope.showing = true;
  94. }
  95. else {
  96. onClick();
  97. onRightClick(event);
  98. }
  99. window.event.returnValue = false;
  100. };
  101. document.addEventListener("click", onClick);
  102. document.addEventListener("mousemove", onMouseMove);
  103. element.addEventListener("contextmenu", onRightClick);
  104. }
  105. return ContextMenu;
  106. })();
  107. AB.ContextMenu = ContextMenu;
  108. })(AB || (AB = { }));