Blame | Last modification | View Log | RSS feed
if(!dojo._hasResource["dijit.layout._LayoutWidget"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit.layout._LayoutWidget"] = true;
dojo.provide("dijit.layout._LayoutWidget");
dojo.require("dijit._Widget");
dojo.require("dijit._Container");
dojo.declare("dijit.layout._LayoutWidget",
[dijit._Widget, dijit._Container, dijit._Contained],
{
// summary
// Mixin for widgets that contain a list of children like SplitContainer.
// Widgets which mixin this code must define layout() to lay out the children
isLayoutContainer: true,
postCreate: function(){
dojo.addClass(this.domNode, "dijitContainer");
},
startup: function(){
// summary:
// Called after all the widgets have been instantiated and their
// dom nodes have been inserted somewhere under document.body.
//
// Widgets should override this method to do any initialization
// dependent on other widgets existing, and then call
// this superclass method to finish things off.
//
// startup() in subclasses shouldn't do anything
// size related because the size of the widget hasn't been set yet.
if(this._started){ return; }
this._started=true;
if(this.getChildren){
dojo.forEach(this.getChildren(), function(child){ child.startup(); });
}
// If I am a top level widget
if(!this.getParent || !this.getParent()){
// Do recursive sizing and layout of all my descendants
// (passing in no argument to resize means that it has to glean the size itself)
this.resize();
// since my parent isn't a layout container, and my style is width=height=100% (or something similar),
// then I need to watch when the window resizes, and size myself accordingly
// (passing in no argument to resize means that it has to glean the size itself)
this.connect(window, 'onresize', function(){this.resize();});
}
},
resize: function(args){
// summary:
// Explicitly set this widget's size (in pixels),
// and then call layout() to resize contents (and maybe adjust child widgets)
//
// args: Object?
// {w: int, h: int, l: int, t: int}
var node = this.domNode;
// set margin box size, unless it wasn't specified, in which case use current size
if(args){
dojo.marginBox(node, args);
// set offset of the node
if(args.t){ node.style.top = args.t + "px"; }
if(args.l){ node.style.left = args.l + "px"; }
}
// If either height or width wasn't specified by the user, then query node for it.
// But note that setting the margin box and then immediately querying dimensions may return
// inaccurate results, so try not to depend on it.
var mb = dojo.mixin(dojo.marginBox(node), args||{});
// Save the size of my content box.
this._contentBox = dijit.layout.marginBox2contentBox(node, mb);
// Callback for widget to adjust size of it's children
this.layout();
},
layout: function(){
// summary
// Widgets override this method to size & position their contents/children.
// When this is called this._contentBox is guaranteed to be set (see resize()).
//
// This is called after startup(), and also when the widget's size has been
// changed.
}
}
);
dijit.layout.marginBox2contentBox = function(/*DomNode*/ node, /*Object*/ mb){
// summary:
// Given the margin-box size of a node, return it's content box size.
// Functions like dojo.contentBox() but is more reliable since it doesn't have
// to wait for the browser to compute sizes.
var cs = dojo.getComputedStyle(node);
var me=dojo._getMarginExtents(node, cs);
var pb=dojo._getPadBorderExtents(node, cs);
return {
l: dojo._toPixelValue(node, cs.paddingLeft),
t: dojo._toPixelValue(node, cs.paddingTop),
w: mb.w - (me.w + pb.w),
h: mb.h - (me.h + pb.h)
};
};
(function(){
var capitalize = function(word){
return word.substring(0,1).toUpperCase() + word.substring(1);
};
var size = function(widget, dim){
// size the child
widget.resize ? widget.resize(dim) : dojo.marginBox(widget.domNode, dim);
// record child's size, but favor our own numbers when we have them.
// the browser lies sometimes
dojo.mixin(widget, dojo.marginBox(widget.domNode));
dojo.mixin(widget, dim);
};
dijit.layout.layoutChildren = function(/*DomNode*/ container, /*Object*/ dim, /*Object[]*/ children){
/**
* summary
* Layout a bunch of child dom nodes within a parent dom node
* container:
* parent node
* dim:
* {l, t, w, h} object specifying dimensions of container into which to place children
* children:
* an array like [ {domNode: foo, layoutAlign: "bottom" }, {domNode: bar, layoutAlign: "client"} ]
*/
// copy dim because we are going to modify it
dim = dojo.mixin({}, dim);
dojo.addClass(container, "dijitLayoutContainer");
// Move "client" elements to the end of the array for layout. a11y dictates that the author
// needs to be able to put them in the document in tab-order, but this algorithm requires that
// client be last.
children = dojo.filter(children, function(item){ return item.layoutAlign != "client"; })
.concat(dojo.filter(children, function(item){ return item.layoutAlign == "client"; }));
// set positions/sizes
dojo.forEach(children, function(child){
var elm = child.domNode,
pos = child.layoutAlign;
// set elem to upper left corner of unused space; may move it later
var elmStyle = elm.style;
elmStyle.left = dim.l+"px";
elmStyle.top = dim.t+"px";
elmStyle.bottom = elmStyle.right = "auto";
dojo.addClass(elm, "dijitAlign" + capitalize(pos));
// set size && adjust record of remaining space.
// note that setting the width of a <div> may affect it's height.
if(pos=="top" || pos=="bottom"){
size(child, { w: dim.w });
dim.h -= child.h;
if(pos=="top"){
dim.t += child.h;
}else{
elmStyle.top = dim.t + dim.h + "px";
}
}else if(pos=="left" || pos=="right"){
size(child, { h: dim.h });
dim.w -= child.w;
if(pos=="left"){
dim.l += child.w;
}else{
elmStyle.left = dim.l + dim.w + "px";
}
}else if(pos=="client"){
size(child, dim);
}
});
};
})();
}