2150 |
mathias |
1 |
if(!dojo._hasResource["dojox.layout.FloatingPane"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
|
|
2 |
dojo._hasResource["dojox.layout.FloatingPane"] = true;
|
|
|
3 |
dojo.provide("dojox.layout.FloatingPane");
|
|
|
4 |
dojo.experimental("dojox.layout.FloatingPane");
|
|
|
5 |
|
|
|
6 |
dojo.require("dojox.layout.ContentPane");
|
|
|
7 |
dojo.require("dijit._Templated");
|
|
|
8 |
dojo.require("dijit._Widget");
|
|
|
9 |
dojo.require("dojo.dnd.move");
|
|
|
10 |
dojo.require("dojox.layout.ResizeHandle");
|
|
|
11 |
|
|
|
12 |
dojo.declare("dojox.layout.FloatingPane",
|
|
|
13 |
[ dojox.layout.ContentPane, dijit._Templated ],
|
|
|
14 |
{
|
|
|
15 |
// summary:
|
|
|
16 |
//
|
|
|
17 |
// Makes a dijit.ContentPane float and draggable by it's title [similar to TitlePane]
|
|
|
18 |
// and over-rides onClick to onDblClick for wipeIn/Out of containerNode
|
|
|
19 |
// provides minimize(dock) / show() and hide() methods, and resize [almost]
|
|
|
20 |
|
|
|
21 |
// closable: Boolean
|
|
|
22 |
// allow closure of this Node
|
|
|
23 |
closable: true,
|
|
|
24 |
|
|
|
25 |
// dockable: Boolean
|
|
|
26 |
// allow minimizing of pane true/false
|
|
|
27 |
dockable: true,
|
|
|
28 |
|
|
|
29 |
// resizable: Boolean
|
|
|
30 |
// allow resizing of pane true/false
|
|
|
31 |
resizable: false,
|
|
|
32 |
|
|
|
33 |
// maxable: Boolean
|
|
|
34 |
// horrible param name for "Can you maximize this floating pane"
|
|
|
35 |
maxable: false,
|
|
|
36 |
|
|
|
37 |
// resizeAxis: String
|
|
|
38 |
// x | xy | y to limit pane's sizing direction
|
|
|
39 |
resizeAxis: "xy",
|
|
|
40 |
|
|
|
41 |
// title: String
|
|
|
42 |
// title to put in titlebar
|
|
|
43 |
title: "",
|
|
|
44 |
|
|
|
45 |
// dockTo: DomNode || null
|
|
|
46 |
// if null, will create private layout.Dock that scrolls with viewport
|
|
|
47 |
// on bottom span of viewport.
|
|
|
48 |
dockTo: null,
|
|
|
49 |
|
|
|
50 |
// duration: Integer
|
|
|
51 |
// time is MS to spend toggling in/out node
|
|
|
52 |
duration: 400,
|
|
|
53 |
|
|
|
54 |
// animation holders for toggle
|
|
|
55 |
_showAnim: null,
|
|
|
56 |
_hideAnim: null,
|
|
|
57 |
|
|
|
58 |
// node in the dock (if docked)
|
|
|
59 |
_dockNode: null,
|
|
|
60 |
|
|
|
61 |
// iconSrc: String
|
|
|
62 |
// [not implemented yet] will be either icon in titlepane to left
|
|
|
63 |
// of Title, and/or icon show when docked in a fisheye-like dock
|
|
|
64 |
// or maybe dockIcon would be better?
|
|
|
65 |
iconSrc: null,
|
|
|
66 |
|
|
|
67 |
contentClass: "dojoxFloatingPaneContent",
|
|
|
68 |
templateString: null,
|
|
|
69 |
templateString:"<div class=\"dojoxFloatingPane\" id=\"${id}\">\n\t<div tabindex=\"0\" waiRole=\"button\" class=\"dojoxFloatingPaneTitle\" dojoAttachPoint=\"focusNode\">\n\t\t<span dojoAttachPoint=\"closeNode\" dojoAttachEvent=\"onclick: close\" class=\"dojoxFloatingCloseIcon\"></span>\n\t\t<span dojoAttachPoint=\"maxNode\" dojoAttachEvent=\"onclick: maximize\" class=\"dojoxFloatingMaximizeIcon\"></span>\n\t\t<span dojoAttachPoint=\"restoreNode\" dojoAttachEvent=\"onclick: _restore\" class=\"dojoxFloatingRestoreIcon\"></span>\t\n\t\t<span dojoAttachPoint=\"dockNode\" dojoAttachEvent=\"onclick: minimize\" class=\"dojoxFloatingMinimizeIcon\"></span>\n\t\t<span dojoAttachPoint=\"titleNode\" class=\"dijitInline dijitTitleNode\"></span>\n\t</div>\n\t<div dojoAttachPoint=\"canvas\" class=\"dojoxFloatingPaneCanvas\">\n\t\t<div dojoAttachPoint=\"containerNode\" waiRole=\"region\" tabindex=\"-1\" class=\"${contentClass}\">\n\t\t</div>\n\t\t<span dojoAttachPoint=\"resizeHandle\" class=\"dojoxFloatingResizeHandle\"></span>\n\t</div>\n</div>\n",
|
|
|
70 |
|
|
|
71 |
_restoreState: {},
|
|
|
72 |
_allFPs: [],
|
|
|
73 |
|
|
|
74 |
postCreate: function(){
|
|
|
75 |
// summary:
|
|
|
76 |
this.setTitle(this.title);
|
|
|
77 |
this.inherited("postCreate",arguments);
|
|
|
78 |
var move = new dojo.dnd.Moveable(this.domNode,{ handle: this.focusNode });
|
|
|
79 |
//this._listener = dojo.subscribe("/dnd/move/start",this,"bringToTop");
|
|
|
80 |
|
|
|
81 |
if(!this.dockable){ this.dockNode.style.display = "none"; }
|
|
|
82 |
if(!this.closable){ this.closeNode.style.display = "none"; }
|
|
|
83 |
if(!this.maxable){
|
|
|
84 |
this.maxNode.style.display = "none";
|
|
|
85 |
this.restoreNode.style.display = "none";
|
|
|
86 |
}
|
|
|
87 |
if(!this.resizable){
|
|
|
88 |
this.resizeHandle.style.display = "none";
|
|
|
89 |
}else{
|
|
|
90 |
var foo = dojo.marginBox(this.domNode);
|
|
|
91 |
this.domNode.style.width = foo.w+"px";
|
|
|
92 |
}
|
|
|
93 |
this._allFPs.push(this);
|
|
|
94 |
},
|
|
|
95 |
|
|
|
96 |
startup: function(){
|
|
|
97 |
this.inherited("startup",arguments);
|
|
|
98 |
|
|
|
99 |
if(this.resizable){
|
|
|
100 |
if(dojo.isIE){
|
|
|
101 |
this.canvas.style.overflow = "auto";
|
|
|
102 |
} else {
|
|
|
103 |
this.containerNode.style.overflow = "auto";
|
|
|
104 |
}
|
|
|
105 |
var tmp = new dojox.layout.ResizeHandle({
|
|
|
106 |
//targetContainer: this.containerNode,
|
|
|
107 |
targetId: this.id,
|
|
|
108 |
resizeAxis: this.resizeAxis
|
|
|
109 |
},this.resizeHandle);
|
|
|
110 |
}
|
|
|
111 |
|
|
|
112 |
if(this.dockable){
|
|
|
113 |
// FIXME: argh.
|
|
|
114 |
tmpName = this.dockTo;
|
|
|
115 |
|
|
|
116 |
if(this.dockTo){
|
|
|
117 |
this.dockTo = dijit.byId(this.dockTo);
|
|
|
118 |
}else{
|
|
|
119 |
this.dockTo = dijit.byId('dojoxGlobalFloatingDock');
|
|
|
120 |
}
|
|
|
121 |
|
|
|
122 |
if(!this.dockTo){
|
|
|
123 |
// we need to make our dock node, and position it against
|
|
|
124 |
// .dojoxDockDefault .. this is a lot. either dockto="node"
|
|
|
125 |
// and fail if node doesn't exist or make the global one
|
|
|
126 |
// once, and use it on empty OR invalid dockTo="" node?
|
|
|
127 |
if(tmpName){
|
|
|
128 |
var tmpId = tmpName;
|
|
|
129 |
var tmpNode = dojo.byId(tmpName);
|
|
|
130 |
}else{
|
|
|
131 |
var tmpNode = document.createElement('div');
|
|
|
132 |
dojo.body().appendChild(tmpNode);
|
|
|
133 |
dojo.addClass(tmpNode,"dojoxFloatingDockDefault");
|
|
|
134 |
var tmpId = 'dojoxGlobalFloatingDock';
|
|
|
135 |
}
|
|
|
136 |
this.dockTo = new dojox.layout.Dock({ id: tmpId, autoPosition: "south" },tmpNode);
|
|
|
137 |
this.dockTo.startup();
|
|
|
138 |
}
|
|
|
139 |
|
|
|
140 |
if((this.domNode.style.display == "none")||(this.domNode.style.visibility == "hidden")){
|
|
|
141 |
// If the FP is created dockable and non-visible, start up docked.
|
|
|
142 |
this.minimize();
|
|
|
143 |
}
|
|
|
144 |
}
|
|
|
145 |
this.connect(this.focusNode,"onmousedown","bringToTop");
|
|
|
146 |
this.connect(this.domNode, "onmousedown","bringToTop");
|
|
|
147 |
},
|
|
|
148 |
|
|
|
149 |
setTitle: function(/* String */ title){
|
|
|
150 |
// summary: Update the string in the titleNode
|
|
|
151 |
this.titleNode.innerHTML = title;
|
|
|
152 |
},
|
|
|
153 |
|
|
|
154 |
close: function(){
|
|
|
155 |
// summary: close and destroy this widget
|
|
|
156 |
if(!this.closable){ return; }
|
|
|
157 |
dojo.unsubscribe(this._listener);
|
|
|
158 |
this.hide(dojo.hitch(this,"destroy"));
|
|
|
159 |
},
|
|
|
160 |
|
|
|
161 |
hide: function(/* Function? */ callback){
|
|
|
162 |
// summary: close but do not destroy this widget
|
|
|
163 |
dojo.fadeOut({
|
|
|
164 |
node:this.domNode,
|
|
|
165 |
duration:this.duration,
|
|
|
166 |
onEnd: dojo.hitch(this,function() {
|
|
|
167 |
this.domNode.style.display = "none";
|
|
|
168 |
this.domNode.style.visibility = "hidden";
|
|
|
169 |
if(this.dockTo){
|
|
|
170 |
this.dockTo._positionDock(null);
|
|
|
171 |
}
|
|
|
172 |
if(callback){
|
|
|
173 |
callback();
|
|
|
174 |
}
|
|
|
175 |
})
|
|
|
176 |
}).play();
|
|
|
177 |
},
|
|
|
178 |
|
|
|
179 |
show: function(/* Function? */callback){
|
|
|
180 |
// summary: show the FloatingPane
|
|
|
181 |
var anim = dojo.fadeIn({node:this.domNode, duration:this.duration,
|
|
|
182 |
beforeBegin: dojo.hitch(this,function(){
|
|
|
183 |
this.domNode.style.display = "";
|
|
|
184 |
this.domNode.style.visibility = "visible";
|
|
|
185 |
this.dockTo._positionDock(null);
|
|
|
186 |
if (this.dockTo) { this.dockTo._positionDock(null); }
|
|
|
187 |
if (typeof callback == "function") { callback(); }
|
|
|
188 |
this._isDocked = false;
|
|
|
189 |
if (this._dockNode) {
|
|
|
190 |
this._dockNode.destroy();
|
|
|
191 |
this._dockNode = null;
|
|
|
192 |
}
|
|
|
193 |
})
|
|
|
194 |
}).play();
|
|
|
195 |
this.resize(dojo.coords(this.domNode));
|
|
|
196 |
},
|
|
|
197 |
|
|
|
198 |
minimize: function(){
|
|
|
199 |
// summary: hide and dock the FloatingPane
|
|
|
200 |
if(!this._isDocked){
|
|
|
201 |
this.hide(dojo.hitch(this,"_dock"));
|
|
|
202 |
}
|
|
|
203 |
},
|
|
|
204 |
|
|
|
205 |
maximize: function(){
|
|
|
206 |
// summary: Make this floatingpane fullscreen (viewport)
|
|
|
207 |
if(this._maximized){ return; }
|
|
|
208 |
this._naturalState = dojo.coords(this.domNode);
|
|
|
209 |
if(this._isDocked){
|
|
|
210 |
this.show();
|
|
|
211 |
setTimeout(dojo.hitch(this,"maximize"),this.duration);
|
|
|
212 |
}
|
|
|
213 |
dojo.addClass(this.focusNode,"floatingPaneMaximized");
|
|
|
214 |
this.resize(dijit.getViewport());
|
|
|
215 |
this._maximized = true;
|
|
|
216 |
},
|
|
|
217 |
|
|
|
218 |
_restore: function(){
|
|
|
219 |
if(this._maximized){
|
|
|
220 |
this.resize(this._naturalState);
|
|
|
221 |
dojo.removeClass(this.focusNode,"floatingPaneMaximized");
|
|
|
222 |
this._maximized = false;
|
|
|
223 |
}
|
|
|
224 |
},
|
|
|
225 |
|
|
|
226 |
_dock: function(){
|
|
|
227 |
if(!this._isDocked){
|
|
|
228 |
this._dockNode = this.dockTo.addNode(this);
|
|
|
229 |
this._isDocked = true;
|
|
|
230 |
}
|
|
|
231 |
},
|
|
|
232 |
|
|
|
233 |
resize: function(/* Object */dim){
|
|
|
234 |
// summary: size the widget and place accordingly
|
|
|
235 |
this._currentState = dim;
|
|
|
236 |
var dns = this.domNode.style;
|
|
|
237 |
|
|
|
238 |
dns.top = dim.t+"px";
|
|
|
239 |
dns.left = dim.l+"px";
|
|
|
240 |
|
|
|
241 |
dns.width = dim.w+"px";
|
|
|
242 |
this.canvas.style.width = dim.w+"px";
|
|
|
243 |
|
|
|
244 |
dns.height = dim.h+"px";
|
|
|
245 |
this.canvas.style.height = (dim.h - this.focusNode.offsetHeight)+"px";
|
|
|
246 |
},
|
|
|
247 |
|
|
|
248 |
_startZ: 100,
|
|
|
249 |
|
|
|
250 |
bringToTop: function(){
|
|
|
251 |
// summary: bring this FloatingPane above all other panes
|
|
|
252 |
var windows = dojo.filter(
|
|
|
253 |
this._allFPs,
|
|
|
254 |
function(i){
|
|
|
255 |
return i !== this;
|
|
|
256 |
},
|
|
|
257 |
this);
|
|
|
258 |
windows.sort(function(a, b){
|
|
|
259 |
return a.domNode.style.zIndex - b.domNode.style.zIndex;
|
|
|
260 |
});
|
|
|
261 |
windows.push(this);
|
|
|
262 |
dojo.forEach(windows, function(w, x){
|
|
|
263 |
w.domNode.style.zIndex = (this._startZ + x * 2);
|
|
|
264 |
dojo.removeClass(w.domNode, "dojoxFloatingPaneFg");
|
|
|
265 |
}, this);
|
|
|
266 |
dojo.addClass(this.domNode, "dojoxFloatingPaneFg");
|
|
|
267 |
},
|
|
|
268 |
|
|
|
269 |
destroy: function(){
|
|
|
270 |
// summary: Destroy this FloatingPane completely
|
|
|
271 |
this._allFPs.splice(dojo.indexOf(this._allFPs, this), 1);
|
|
|
272 |
this.inherited("destroy", arguments);
|
|
|
273 |
}
|
|
|
274 |
});
|
|
|
275 |
|
|
|
276 |
|
|
|
277 |
dojo.declare("dojox.layout.Dock", [dijit._Widget,dijit._Templated], {
|
|
|
278 |
// summary:
|
|
|
279 |
// a widget that attaches to a node and keeps track of incoming / outgoing FloatingPanes
|
|
|
280 |
// and handles layout
|
|
|
281 |
|
|
|
282 |
templateString: '<div class="dojoxDock"><ul dojoAttachPoint="containerNode" class="dojoxDockList"></ul></div>',
|
|
|
283 |
|
|
|
284 |
// private _docked: array of panes currently in our dock
|
|
|
285 |
_docked: [],
|
|
|
286 |
|
|
|
287 |
_inPositioning: false,
|
|
|
288 |
|
|
|
289 |
autoPosition: false,
|
|
|
290 |
|
|
|
291 |
addNode: function(refNode){
|
|
|
292 |
// summary: instert a dockNode refernce into the dock
|
|
|
293 |
var div = document.createElement('li');
|
|
|
294 |
this.containerNode.appendChild(div);
|
|
|
295 |
var node = new dojox.layout._DockNode({ title: refNode.title, paneRef: refNode },div);
|
|
|
296 |
node.startup();
|
|
|
297 |
return node;
|
|
|
298 |
},
|
|
|
299 |
|
|
|
300 |
startup: function(){
|
|
|
301 |
// summary: attaches some event listeners
|
|
|
302 |
if (this.id == "dojoxGlobalFloatingDock" || this.isFixedDock) {
|
|
|
303 |
// attach window.onScroll, and a position like in presentation/dialog
|
|
|
304 |
dojo.connect(window,'onresize',this,"_positionDock");
|
|
|
305 |
dojo.connect(window,'onscroll',this,"_positionDock");
|
|
|
306 |
if(dojo.isIE){
|
|
|
307 |
dojo.connect(this.domNode,'onresize', this,"_positionDock");
|
|
|
308 |
}
|
|
|
309 |
}
|
|
|
310 |
this._positionDock(null);
|
|
|
311 |
this.inherited("startup",arguments);
|
|
|
312 |
},
|
|
|
313 |
|
|
|
314 |
_positionDock: function(/* Event? */e){
|
|
|
315 |
if(!this._inPositioning){
|
|
|
316 |
if(this.autoPosition == "south"){
|
|
|
317 |
// Give some time for scrollbars to appear/disappear
|
|
|
318 |
setTimeout(dojo.hitch(this, function() {
|
|
|
319 |
this._inPositiononing = true;
|
|
|
320 |
var viewport = dijit.getViewport();
|
|
|
321 |
var s = this.domNode.style;
|
|
|
322 |
s.left = viewport.l + "px";
|
|
|
323 |
s.width = (viewport.w-2) + "px";
|
|
|
324 |
s.top = (viewport.h + viewport.t) - this.domNode.offsetHeight + "px";
|
|
|
325 |
this._inPositioning = false;
|
|
|
326 |
}), 500);
|
|
|
327 |
}
|
|
|
328 |
}
|
|
|
329 |
}
|
|
|
330 |
|
|
|
331 |
|
|
|
332 |
});
|
|
|
333 |
|
|
|
334 |
dojo.declare("dojox.layout._DockNode", [dijit._Widget,dijit._Templated], {
|
|
|
335 |
// summary:
|
|
|
336 |
// dojox.layout._DockNode is a private widget used to keep track of
|
|
|
337 |
// which pane is docked.
|
|
|
338 |
|
|
|
339 |
// title: String
|
|
|
340 |
// shown in dock icon. should read parent iconSrc?
|
|
|
341 |
title: "",
|
|
|
342 |
|
|
|
343 |
// paneRef: Widget
|
|
|
344 |
// reference to the FloatingPane we reprasent in any given dock
|
|
|
345 |
paneRef: null,
|
|
|
346 |
|
|
|
347 |
templateString: '<li dojoAttachEvent="onclick: restore" class="dojoxDockNode">'+
|
|
|
348 |
'<span dojoAttachPoint="restoreNode" class="dojoxDockRestoreButton" dojoAttachEvent="onclick: restore"></span>'+
|
|
|
349 |
'<span class="dojoxDockTitleNode" dojoAttachPoint="titleNode">${title}</span>'+
|
|
|
350 |
'</li>',
|
|
|
351 |
|
|
|
352 |
restore: function(){
|
|
|
353 |
// summary: remove this dock item from parent dock, and call show() on reffed floatingpane
|
|
|
354 |
this.paneRef.show();
|
|
|
355 |
this.paneRef.bringToTop();
|
|
|
356 |
this.destroy();
|
|
|
357 |
}
|
|
|
358 |
|
|
|
359 |
});
|
|
|
360 |
|
|
|
361 |
}
|