You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
190 lines
6.9 KiB
190 lines
6.9 KiB
define([ |
|
"dojo/_base/lang", // lang.mixin |
|
"../_Widget", |
|
"../_Container", |
|
"../_Contained", |
|
"../Viewport", |
|
"dojo/_base/declare", // declare |
|
"dojo/dom-class", // domClass.add domClass.remove |
|
"dojo/dom-geometry", // domGeometry.marginBox |
|
"dojo/dom-style" // domStyle.getComputedStyle |
|
], function(lang, _Widget, _Container, _Contained, Viewport, |
|
declare, domClass, domGeometry, domStyle){ |
|
|
|
// module: |
|
// dijit/layout/_LayoutWidget |
|
|
|
|
|
return declare("dijit.layout._LayoutWidget", [_Widget, _Container, _Contained], { |
|
// summary: |
|
// Base class for a _Container widget which is responsible for laying out its children. |
|
// Widgets which mixin this code must define layout() to manage placement and sizing of the children. |
|
|
|
// baseClass: [protected extension] String |
|
// This class name is applied to the widget's domNode |
|
// and also may be used to generate names for sub nodes, |
|
// for example dijitTabContainer-content. |
|
baseClass: "dijitLayoutContainer", |
|
|
|
// isLayoutContainer: [protected] Boolean |
|
// Indicates that this widget is going to call resize() on its |
|
// children widgets, setting their size, when they become visible. |
|
isLayoutContainer: true, |
|
|
|
// Cancel _WidgetBase's _setTitleAttr because we don't want the title property (used to specify |
|
// tab labels) to be set as an attribute on this.domNode... otherwise a tooltip shows up over the |
|
// entire widget. |
|
_setTitleAttr: null, |
|
|
|
buildRendering: function(){ |
|
this.inherited(arguments); |
|
domClass.add(this.domNode, "dijitContainer"); |
|
}, |
|
|
|
startup: function(){ |
|
// summary: |
|
// Called after all the widgets have been instantiated and their |
|
// dom nodes have been inserted somewhere under <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; } |
|
|
|
// Need to call inherited first - so that child widgets get started |
|
// up correctly |
|
this.inherited(arguments); |
|
|
|
// If I am a not being controlled by a parent layout widget... |
|
var parent = this.getParent && this.getParent(); |
|
if(!(parent && parent.isLayoutContainer)){ |
|
// 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 *may be* width=height=100% |
|
// or something similar (either set directly or via a CSS class), |
|
// monitor when viewport size changes so that I can re-layout. |
|
this.own(Viewport.on("resize", lang.hitch(this, "resize"))); |
|
} |
|
}, |
|
|
|
resize: function(changeSize, resultSize){ |
|
// summary: |
|
// Call this to resize a widget, or after its size has changed. |
|
// description: |
|
// ####Change size mode: |
|
// |
|
// When changeSize is specified, changes the marginBox of this widget |
|
// and forces it to re-layout its contents accordingly. |
|
// changeSize may specify height, width, or both. |
|
// |
|
// If resultSize is specified it indicates the size the widget will |
|
// become after changeSize has been applied. |
|
// |
|
// ####Notification mode: |
|
// |
|
// When changeSize is null, indicates that the caller has already changed |
|
// the size of the widget, or perhaps it changed because the browser |
|
// window was resized. Tells widget to re-layout its contents accordingly. |
|
// |
|
// If resultSize is also specified it indicates the size the widget has |
|
// become. |
|
// |
|
// In either mode, this method also: |
|
// |
|
// 1. Sets this._borderBox and this._contentBox to the new size of |
|
// the widget. Queries the current domNode size if necessary. |
|
// 2. Calls layout() to resize contents (and maybe adjust child widgets). |
|
// changeSize: Object? |
|
// Sets the widget to this margin-box size and position. |
|
// May include any/all of the following properties: |
|
// | {w: int, h: int, l: int, t: int} |
|
// resultSize: Object? |
|
// The margin-box size of this widget after applying changeSize (if |
|
// changeSize is specified). If caller knows this size and |
|
// passes it in, we don't need to query the browser to get the size. |
|
// | {w: int, h: int} |
|
|
|
var node = this.domNode; |
|
|
|
// set margin box size, unless it wasn't specified, in which case use current size |
|
if(changeSize){ |
|
domGeometry.setMarginBox(node, changeSize); |
|
} |
|
|
|
// 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 = resultSize || {}; |
|
lang.mixin(mb, changeSize || {}); // changeSize overrides resultSize |
|
if( !("h" in mb) || !("w" in mb) ){ |
|
mb = lang.mixin(domGeometry.getMarginBox(node), mb); // just use domGeometry.marginBox() to fill in missing values |
|
} |
|
|
|
// Compute and save the size of my border box and content box |
|
// (w/out calling domGeometry.getContentBox() since that may fail if size was recently set) |
|
var cs = domStyle.getComputedStyle(node); |
|
var me = domGeometry.getMarginExtents(node, cs); |
|
var be = domGeometry.getBorderExtents(node, cs); |
|
var bb = (this._borderBox = { |
|
w: mb.w - (me.w + be.w), |
|
h: mb.h - (me.h + be.h) |
|
}); |
|
var pe = domGeometry.getPadExtents(node, cs); |
|
this._contentBox = { |
|
l: domStyle.toPixelValue(node, cs.paddingLeft), |
|
t: domStyle.toPixelValue(node, cs.paddingTop), |
|
w: bb.w - pe.w, |
|
h: bb.h - pe.h |
|
}; |
|
|
|
// Callback for widget to adjust size of its children |
|
this.layout(); |
|
}, |
|
|
|
layout: function(){ |
|
// summary: |
|
// Widgets override this method to size and 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. |
|
// tags: |
|
// protected extension |
|
}, |
|
|
|
_setupChild: function(/*dijit/_WidgetBase*/child){ |
|
// summary: |
|
// Common setup for initial children and children which are added after startup |
|
// tags: |
|
// protected extension |
|
|
|
var cls = this.baseClass + "-child " |
|
+ (child.baseClass ? this.baseClass + "-" + child.baseClass : ""); |
|
domClass.add(child.domNode, cls); |
|
}, |
|
|
|
addChild: function(/*dijit/_WidgetBase*/ child, /*Integer?*/ insertIndex){ |
|
// Overrides _Container.addChild() to call _setupChild() |
|
this.inherited(arguments); |
|
if(this._started){ |
|
this._setupChild(child); |
|
} |
|
}, |
|
|
|
removeChild: function(/*dijit/_WidgetBase*/ child){ |
|
// Overrides _Container.removeChild() to remove class added by _setupChild() |
|
var cls = this.baseClass + "-child" |
|
+ (child.baseClass ? |
|
" " + this.baseClass + "-" + child.baseClass : ""); |
|
domClass.remove(child.domNode, cls); |
|
|
|
this.inherited(arguments); |
|
} |
|
}); |
|
});
|
|
|