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