BoundingBoxController.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /*
  2. Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
  3. Available via Academic Free License >= 2.1 OR the modified BSD license.
  4. see: http://dojotoolkit.org/license for details
  5. */
  6. if(!dojo._hasResource["dojox.dnd.BoundingBoxController"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojox.dnd.BoundingBoxController"] = true;
  8. dojo.provide("dojox.dnd.BoundingBoxController");
  9. dojo.declare(
  10. "dojox.dnd.BoundingBoxController",
  11. null,
  12. {
  13. // summary: Allows the user draw bounding boxes around nodes on the page.
  14. // Publishes to the "/dojox/dnd/bounding" topic to tell the selector to check
  15. // to see whether any dnd items fall within the coordinates of the bounding box
  16. // x,y start and end coordinates for the bounding box
  17. _startX: null,
  18. _startY: null,
  19. _endX: null,
  20. _endY: null,
  21. constructor: function(sources, domNode){
  22. // summary:
  23. // Sets mouse handlers for the document to capture when a user
  24. // is trying to draw a bounding box.
  25. // sources: Array:
  26. // an array of dojox.dnd.Selectors which need to be aware of
  27. // the positioning of the bounding box.
  28. // domNode: String|DomNode:
  29. // the DOM node or id which represents the bounding box on the page.
  30. this.events = [
  31. dojo.connect(dojo.doc, "onmousedown", this, "_onMouseDown"),
  32. dojo.connect(dojo.doc, "onmouseup", this, "_onMouseUp"),
  33. // cancel text selection and text dragging
  34. //dojo.connect(dojo.doc, "ondragstart", dojo.stopEvent),
  35. //dojo.connect(dojo.doc, "onselectstart", dojo.stopEvent),
  36. // when a user is scrolling using a scrollbar, don't draw the bounding box.
  37. dojo.connect(dojo.doc, "onscroll", this, "_finishSelecting")
  38. ];
  39. // set up a subscription so the client can easily cancel a user drawing a bounding box.
  40. this.subscriptions = [
  41. dojo.subscribe("/dojox/bounding/cancel", this, "_finishSelecting")
  42. ];
  43. dojo.forEach(sources, function(item){
  44. // listen for "/dojox/dnd/bounding" events eminating from the bounding box.
  45. // for each of the dojox.dnd.selectors passed in args.
  46. if(item.selectByBBox){
  47. this.subscriptions.push(dojo.subscribe("/dojox/dnd/bounding", item, "selectByBBox"));
  48. }
  49. }, this)
  50. this.domNode = dojo.byId(domNode);
  51. dojo.style(this.domNode, {
  52. position: "absolute",
  53. display: "none"
  54. });
  55. },
  56. destroy: function(){
  57. // summary:
  58. // prepares this object to be garbage-collected
  59. dojo.forEach(this.events, dojo.disconnect);
  60. dojo.forEach(this.subscriptions, dojo.unsubscribe);
  61. this.domNode = null;
  62. },
  63. boundingBoxIsViable: function(){
  64. // summary: Override-able by the client as an extra check to ensure that a bounding
  65. // box is viable. In some instances, it might not make sense that
  66. // a mouse down -> mouse move -> mouse up interaction represents a bounding box.
  67. // For example, if a dialog is open the client might want to suppress a bounding
  68. // box. This function could be used by the client to ensure that a bounding box is only
  69. // drawn on the document when certain conditions are met.
  70. return true;
  71. },
  72. _onMouseDown: function(evt){
  73. // summary: Executed when the user mouses down on the document. Resets the
  74. // this._startX and this._startY member variables.
  75. // evt: Object: the mouse event which caused this callback to fire.
  76. if(dojo.mouseButtons.isLeft(evt)){
  77. if(this._startX === null){
  78. this._startX = evt.clientX;
  79. this._startY = evt.clientY;
  80. }
  81. this.events.push(
  82. dojo.connect(dojo.doc, "onmousemove", this, "_onMouseMove")
  83. );
  84. }
  85. },
  86. _onMouseMove: function(evt){
  87. // summary: Executed when the user moves the mouse over the document. Delegates to
  88. // this._drawBoundingBox if the user is trying to draw a bounding box.
  89. // whether the user was drawing a bounding box and publishes to the
  90. // "/dojox/dnd/bounding" topic if the user is finished drawing their bounding box.
  91. // evt: Object: the mouse event which caused this callback to fire.
  92. this._endX = evt.clientX;
  93. this._endY = evt.clientY;
  94. this._drawBoundingBox();
  95. },
  96. _onMouseUp: function(evt){
  97. // summary: Executed when the users mouses up on the document. Checks to see
  98. // whether the user was drawing a bounding box and publishes to the
  99. // "/dojox/dnd/bounding" topic if the user is finished drawing their bounding box.
  100. // evt: Object: the mouse event which caused this callback to fire.
  101. if(this._endX !== null && this.boundingBoxIsViable()){
  102. // the user has moused up ... tell the selector to check to see whether
  103. // any nodes within the bounding box need to be selected.
  104. dojo.publish("/dojox/dnd/bounding", [this._startX, this._startY, this._endX, this._endY]);
  105. }
  106. this._finishSelecting();
  107. },
  108. _finishSelecting: function(){
  109. // summary: hide the bounding box and reset for the next time around
  110. if(this._startX !== null){
  111. dojo.disconnect(this.events.pop());
  112. dojo.style(this.domNode, "display", "none");
  113. this._startX = this._endX = null;
  114. }
  115. },
  116. _drawBoundingBox: function(){
  117. // summary: draws the bounding box over the document.
  118. dojo.style(this.domNode, {
  119. left: Math.min(this._startX, this._endX) + "px",
  120. top: Math.min(this._startY, this._endY) + "px",
  121. width: Math.abs(this._startX - this._endX) + "px",
  122. height: Math.abs(this._startY - this._endY) + "px",
  123. display: ""
  124. });
  125. }
  126. }
  127. );
  128. }