_LayoutWidget.js.uncompressed.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. define("dijit/layout/_LayoutWidget", [
  2. "dojo/_base/lang", // lang.mixin
  3. "../_Widget",
  4. "../_Container",
  5. "../_Contained",
  6. "../Viewport",
  7. "dojo/_base/declare", // declare
  8. "dojo/dom-class", // domClass.add domClass.remove
  9. "dojo/dom-geometry", // domGeometry.marginBox
  10. "dojo/dom-style" // domStyle.getComputedStyle
  11. ], function(lang, _Widget, _Container, _Contained, Viewport,
  12. declare, domClass, domGeometry, domStyle){
  13. // module:
  14. // dijit/layout/_LayoutWidget
  15. return declare("dijit.layout._LayoutWidget", [_Widget, _Container, _Contained], {
  16. // summary:
  17. // Base class for a _Container widget which is responsible for laying out its children.
  18. // Widgets which mixin this code must define layout() to manage placement and sizing of the children.
  19. // baseClass: [protected extension] String
  20. // This class name is applied to the widget's domNode
  21. // and also may be used to generate names for sub nodes,
  22. // for example dijitTabContainer-content.
  23. baseClass: "dijitLayoutContainer",
  24. // isLayoutContainer: [protected] Boolean
  25. // Indicates that this widget is going to call resize() on its
  26. // children widgets, setting their size, when they become visible.
  27. isLayoutContainer: true,
  28. buildRendering: function(){
  29. this.inherited(arguments);
  30. domClass.add(this.domNode, "dijitContainer");
  31. },
  32. startup: function(){
  33. // summary:
  34. // Called after all the widgets have been instantiated and their
  35. // dom nodes have been inserted somewhere under win.doc.body.
  36. //
  37. // Widgets should override this method to do any initialization
  38. // dependent on other widgets existing, and then call
  39. // this superclass method to finish things off.
  40. //
  41. // startup() in subclasses shouldn't do anything
  42. // size related because the size of the widget hasn't been set yet.
  43. if(this._started){ return; }
  44. // Need to call inherited first - so that child widgets get started
  45. // up correctly
  46. this.inherited(arguments);
  47. // If I am a not being controlled by a parent layout widget...
  48. var parent = this.getParent && this.getParent();
  49. if(!(parent && parent.isLayoutContainer)){
  50. // Do recursive sizing and layout of all my descendants
  51. // (passing in no argument to resize means that it has to glean the size itself)
  52. this.resize();
  53. // Since my parent isn't a layout container, and my style *may be* width=height=100%
  54. // or something similar (either set directly or via a CSS class),
  55. // monitor when viewport size changes so that I can re-layout.
  56. this.own(Viewport.on("resize", lang.hitch(this, "resize")));
  57. }
  58. },
  59. resize: function(changeSize, resultSize){
  60. // summary:
  61. // Call this to resize a widget, or after its size has changed.
  62. // description:
  63. // ####Change size mode:
  64. //
  65. // When changeSize is specified, changes the marginBox of this widget
  66. // and forces it to re-layout its contents accordingly.
  67. // changeSize may specify height, width, or both.
  68. //
  69. // If resultSize is specified it indicates the size the widget will
  70. // become after changeSize has been applied.
  71. //
  72. // ####Notification mode:
  73. //
  74. // When changeSize is null, indicates that the caller has already changed
  75. // the size of the widget, or perhaps it changed because the browser
  76. // window was resized. Tells widget to re-layout its contents accordingly.
  77. //
  78. // If resultSize is also specified it indicates the size the widget has
  79. // become.
  80. //
  81. // In either mode, this method also:
  82. //
  83. // 1. Sets this._borderBox and this._contentBox to the new size of
  84. // the widget. Queries the current domNode size if necessary.
  85. // 2. Calls layout() to resize contents (and maybe adjust child widgets).
  86. // changeSize: Object?
  87. // Sets the widget to this margin-box size and position.
  88. // May include any/all of the following properties:
  89. // | {w: int, h: int, l: int, t: int}
  90. // resultSize: Object?
  91. // The margin-box size of this widget after applying changeSize (if
  92. // changeSize is specified). If caller knows this size and
  93. // passes it in, we don't need to query the browser to get the size.
  94. // | {w: int, h: int}
  95. var node = this.domNode;
  96. // set margin box size, unless it wasn't specified, in which case use current size
  97. if(changeSize){
  98. domGeometry.setMarginBox(node, changeSize);
  99. }
  100. // If either height or width wasn't specified by the user, then query node for it.
  101. // But note that setting the margin box and then immediately querying dimensions may return
  102. // inaccurate results, so try not to depend on it.
  103. var mb = resultSize || {};
  104. lang.mixin(mb, changeSize || {}); // changeSize overrides resultSize
  105. if( !("h" in mb) || !("w" in mb) ){
  106. mb = lang.mixin(domGeometry.getMarginBox(node), mb); // just use domGeometry.marginBox() to fill in missing values
  107. }
  108. // Compute and save the size of my border box and content box
  109. // (w/out calling domGeometry.getContentBox() since that may fail if size was recently set)
  110. var cs = domStyle.getComputedStyle(node);
  111. var me = domGeometry.getMarginExtents(node, cs);
  112. var be = domGeometry.getBorderExtents(node, cs);
  113. var bb = (this._borderBox = {
  114. w: mb.w - (me.w + be.w),
  115. h: mb.h - (me.h + be.h)
  116. });
  117. var pe = domGeometry.getPadExtents(node, cs);
  118. this._contentBox = {
  119. l: domStyle.toPixelValue(node, cs.paddingLeft),
  120. t: domStyle.toPixelValue(node, cs.paddingTop),
  121. w: bb.w - pe.w,
  122. h: bb.h - pe.h
  123. };
  124. // Callback for widget to adjust size of its children
  125. this.layout();
  126. },
  127. layout: function(){
  128. // summary:
  129. // Widgets override this method to size and position their contents/children.
  130. // When this is called this._contentBox is guaranteed to be set (see resize()).
  131. //
  132. // This is called after startup(), and also when the widget's size has been
  133. // changed.
  134. // tags:
  135. // protected extension
  136. },
  137. _setupChild: function(/*dijit/_WidgetBase*/child){
  138. // summary:
  139. // Common setup for initial children and children which are added after startup
  140. // tags:
  141. // protected extension
  142. var cls = this.baseClass + "-child "
  143. + (child.baseClass ? this.baseClass + "-" + child.baseClass : "");
  144. domClass.add(child.domNode, cls);
  145. },
  146. addChild: function(/*dijit/_WidgetBase*/ child, /*Integer?*/ insertIndex){
  147. // Overrides _Container.addChild() to call _setupChild()
  148. this.inherited(arguments);
  149. if(this._started){
  150. this._setupChild(child);
  151. }
  152. },
  153. removeChild: function(/*dijit/_WidgetBase*/ child){
  154. // Overrides _Container.removeChild() to remove class added by _setupChild()
  155. var cls = this.baseClass + "-child"
  156. + (child.baseClass ?
  157. " " + this.baseClass + "-" + child.baseClass : "");
  158. domClass.remove(child.domNode, cls);
  159. this.inherited(arguments);
  160. }
  161. });
  162. });