Pan.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. // wrapped by build app
  2. define("dojox/drawing/ui/dom/Pan", ["dijit","dojo","dojox","dojo/require!dojox/drawing/plugins/_Plugin"], function(dijit,dojo,dojox){
  3. dojo.provide("dojox.drawing.ui.dom.Pan");
  4. dojo.require("dojox.drawing.plugins._Plugin");
  5. dojo.deprecated("dojox.drawing.ui.dom.Pan", "It may not even make it to the 1.4 release.", 1.4);
  6. dojox.drawing.ui.dom.Pan = dojox.drawing.util.oo.declare(
  7. // NOTE:
  8. // dojox.drawing.ui.dom.Pan is DEPRECATED.
  9. // This was a temporary DOM solution. Use the non-dom
  10. // tools for Toobar and Plugins.
  11. //
  12. // summary:
  13. // A plugin that allows for a scrolling canvas. An action
  14. // tool is added to the toolbar that allows for panning. Holding
  15. // the space bar is a shortcut to that action. The canvas will
  16. // only pan and scroll if there are objects out of the viewable
  17. // area.
  18. // example:
  19. // | <div dojoType="dojox.drawing.Toolbar" drawingId="drawingNode" class="drawingToolbar vertical">
  20. // | <div tool="dojox.drawing.tools.Line" selected="true">Line</div>
  21. // | <div plugin="dojox.drawing.ui.dom.Pan" options="{}">Pan</div>
  22. // | </div>
  23. //
  24. dojox.drawing.plugins._Plugin,
  25. function(options){
  26. this.domNode = options.node;
  27. var _scrollTimeout;
  28. dojo.connect(this.domNode, "click", this, "onSetPan");
  29. dojo.connect(this.keys, "onKeyUp", this, "onKeyUp");
  30. dojo.connect(this.keys, "onKeyDown", this, "onKeyDown");
  31. dojo.connect(this.anchors, "onAnchorUp", this, "checkBounds");
  32. dojo.connect(this.stencils, "register", this, "checkBounds");
  33. dojo.connect(this.canvas, "resize", this, "checkBounds");
  34. dojo.connect(this.canvas, "setZoom", this, "checkBounds");
  35. dojo.connect(this.canvas, "onScroll", this, function(){
  36. if(this._blockScroll){
  37. this._blockScroll = false;
  38. return;
  39. }
  40. _scrollTimeout && clearTimeout(_scrollTimeout);
  41. _scrollTimeout = setTimeout(dojo.hitch(this, "checkBounds"), 200);
  42. });
  43. this._mouseHandle = this.mouse.register(this);
  44. // This HAS to be called after setting initial objects or things get screwy.
  45. //this.checkBounds();
  46. },{
  47. selected:false,
  48. type:"dojox.drawing.ui.dom.Pan",
  49. onKeyUp: function(evt){
  50. if(evt.keyCode == 32){
  51. this.onSetPan(false);
  52. }
  53. },
  54. onKeyDown: function(evt){
  55. if(evt.keyCode == 32){
  56. this.onSetPan(true);
  57. }
  58. },
  59. onSetPan: function(/*Boolean | Event*/ bool){
  60. if(bool === true || bool === false){
  61. this.selected = !bool;
  62. }
  63. if(this.selected){
  64. this.selected = false;
  65. dojo.removeClass(this.domNode, "selected");
  66. }else{
  67. this.selected = true;
  68. dojo.addClass(this.domNode, "selected");
  69. }
  70. this.mouse.setEventMode(this.selected ? "pan" : "");
  71. },
  72. onPanDrag: function(obj){
  73. var x = obj.x - obj.last.x;
  74. var y = obj.y - obj.last.y;
  75. this.canvas.domNode.parentNode.scrollTop -= obj.move.y;
  76. this.canvas.domNode.parentNode.scrollLeft -= obj.move.x;
  77. this.canvas.onScroll();
  78. },
  79. onStencilUp: function(obj){
  80. // this gets called even on click-off because of the
  81. // issues with TextBlock deselection
  82. this.checkBounds();
  83. },
  84. onStencilDrag: function(obj){
  85. // this gets called even on click-off because of the
  86. // issues with TextBlock deselection
  87. //this.checkBounds();
  88. },
  89. checkBounds: function(){
  90. //watch("CHECK BOUNDS DISABLED", true); return;
  91. // summary:
  92. // Scans all items on the canvas and checks if they are out of
  93. // bounds. If so, a scroll bar (in Canvas) is shown. If the position
  94. // is left or top, the canvas is scrolled all items are relocated
  95. // the distance of the scroll. Ideally, it should look as if the
  96. // items do not move.
  97. // logging stuff here so it can be turned on and off. This method is
  98. // very high maintenance.
  99. var log = function(){
  100. ///console.log.apply(console, arguments);
  101. };
  102. var warn = function(){
  103. //console.warn.apply(console, arguments);
  104. };
  105. //console.clear();
  106. //console.time("check bounds");
  107. var t=Infinity, r=-Infinity, b=-Infinity, l=Infinity,
  108. sx=0, sy=0, dy=0, dx=0,
  109. mx = this.stencils.group ? this.stencils.group.getTransform() : {dx:0, dy:0},
  110. sc = this.mouse.scrollOffset(),
  111. // scY, scX: the scrollbar creates the need for extra dimension
  112. scY = sc.left ? 10 : 0,
  113. scX = sc.top ? 10 : 0,
  114. // ch, cw: the current size of the canvas
  115. ch = this.canvas.height,
  116. cw = this.canvas.width,
  117. z = this.canvas.zoom,
  118. // pch, pcw: the normal size of the canvas (not scrolled)
  119. // these could change if the container resizes.
  120. pch = this.canvas.parentHeight,
  121. pcw = this.canvas.parentWidth;
  122. this.stencils.withSelected(function(m){
  123. var o = m.getBounds();
  124. warn("SEL BOUNDS:", o);
  125. t = Math.min(o.y1 + mx.dy, t);
  126. r = Math.max(o.x2 + mx.dx, r);
  127. b = Math.max(o.y2 + mx.dy, b);
  128. l = Math.min(o.x1 + mx.dx, l);
  129. });
  130. this.stencils.withUnselected(function(m){
  131. var o = m.getBounds();
  132. warn("UN BOUNDS:", o);
  133. t = Math.min(o.y1, t);
  134. r = Math.max(o.x2, r);
  135. b = Math.max(o.y2, b);
  136. l = Math.min(o.x1, l);
  137. });
  138. b *= z;
  139. var xscroll = 0, yscroll = 0;
  140. log("Bottom test", "b:", b, "z:", z, "ch:", ch, "pch:", pch, "top:", sc.top, "sy:", sy);
  141. if(b > pch || sc.top ){
  142. log("*bottom scroll*");
  143. // item off bottom
  144. ch = Math.max(b, pch + sc.top);
  145. sy = sc.top;
  146. xscroll += this.canvas.getScrollWidth();
  147. }else if(!sy && ch>pch){
  148. log("*bottom remove*");
  149. // item moved from bottom
  150. ch = pch;
  151. }
  152. r *= z;
  153. if(r > pcw || sc.left){
  154. //log("*right scroll*");
  155. // item off right
  156. cw = Math.max(r, pcw + sc.left);
  157. sx = sc.left;
  158. yscroll += this.canvas.getScrollWidth();
  159. }else if(!sx && cw>pcw){
  160. //log("*right remove*");
  161. // item moved from right
  162. cw = pcw;
  163. }
  164. // add extra space for scrollbars
  165. // double it to give some breathing room
  166. cw += xscroll*2;
  167. ch += yscroll*2;
  168. this._blockScroll = true;
  169. // selected items are not transformed. The selection itself is
  170. // and the items are on de-select
  171. this.stencils.group && this.stencils.group.applyTransform({dx:dx, dy:dy});
  172. // non-selected items are transformed
  173. this.stencils.withUnselected(function(m){
  174. m.transformPoints({dx:dx, dy:dy});
  175. });
  176. this.canvas.setDimensions(cw, ch, sx, sy);
  177. //console.timeEnd("check bounds");
  178. }
  179. }
  180. );
  181. dojox.drawing.ui.dom.Pan.setup = {
  182. name:"dojox.drawing.ui.dom.Pan",
  183. tooltip:"Pan Tool",
  184. iconClass:"iconPan"
  185. };
  186. dojox.drawing.register(dojox.drawing.ui.dom.Pan.setup, "plugin");
  187. });