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